[LeetCode] 251. Flatten 2D Vector 壓平二維向量


 

Implement an iterator to flatten a 2d vector.

For example,
Given 2d vector =

[
  [1,2],
  [3],
  [4,5,6]
]

 

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,2,3,4,5,6].

Hint:

  1. How many variables do you need to keep track?
  2. Two variables is all you need. Try with x and y.
  3. Beware of empty rows. It could be the first few rows.
  4. To write correct code, think about the invariant to maintain. What is it?
  5. The invariant is x and y must always point to a valid point in the 2d vector. Should you maintain your invariant ahead of time or right when you need it?
  6. Not sure? Think about how you would implement hasNext(). Which is more complex?
  7. Common logic in two different places should be refactored into a common method.

Follow up:
As an added challenge, try to code it using only iterators in C++ or iterators in Java.

 

這道題讓我們壓平一個二維向量數組,並且實現一個 iterator 的功能,包括 next 和 hasNext 函數,那么最簡單的方法就是將二維數組按順序先存入到一個一維數組里,然后此時只要維護一個變量i來記錄當前遍歷到的位置,hasNext 函數看當前坐標是否小於元素總數,next 函數即為取出當前位置元素,坐標后移一位,參見代碼如下:                      

 

解法一:

class Vector2D {
public:
    Vector2D(vector<vector<int>>& vec2d) {
        for (auto a : vec2d) {
            v.insert(v.end(), a.begin(), a.end());
        }    
    }
    int next() {
        return v[i++];
    }
    bool hasNext() {
        return i < v.size();
    }
private:
    vector<int> v;
    int i = 0;
};

 

下面我們來看另一種解法,不直接轉換為一維數組,而是維護兩個變量x和y,將x和y初始化為0,對於 hasNext 函數,檢查當前x是否小於總行數,y是否和當前行的列數相同,如果相同,說明要轉到下一行,則x自增1,y初始化為0,若此時x還是小於總行數,說明下一個值可以被取出來,那么在 next 函數就可以直接取出行為x,列為y的數字,並將y自增1,參見代碼如下:

 

解法二:

class Vector2D {
public:
    Vector2D(vector<vector<int>>& vec2d): data(vec2d), x(0), y(0) {}

    int next() {
        hasNext();
        return data[x][y++];
    }
    bool hasNext() {
        while (x < data.size() && y == data[x].size()) {
            ++x; 
            y = 0;
        }
        return x < data.size();
    }    
private:
    vector<vector<int>> data;
    int x, y;
};

 

題目中的 Follow up 讓我們用 interator 來做,C++中 iterator 不像 Java 中的那么強大,自己本身並沒有包含 next 和 hasNext 函數,所以得自己來實現,將x定義為行的 iterator,再用個 end 指向二維數組的末尾,定義一個整型變量y來指向列位置,實現思路和上一種解法完全相同,只是寫法略有不同,參見代碼如下:

 

解法三:

class Vector2D {
public:
    Vector2D(vector<vector<int>>& vec2d): x(vec2d.begin()), end(vec2d.end()) {}
    
    int next() {
        hasNext();
        return (*x)[y++];
    }
    bool hasNext() {
        while (x != end && y == (*x).size()) {
            ++x; 
            y = 0;
        }
        return x != end;
    }
private:
    vector<vector<int>>::iterator x, end;
    int y = 0;
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/251

 

類似題目:

Binary Search Tree Iterator

Zigzag Iterator

Peeking Iterator

Flatten Nested List Iterator

 

參考資料:

https://leetcode.com/problems/flatten-2d-vector/

https://leetcode.com/problems/flatten-2d-vector/discuss/67652/7-9-lines-added-Java-and-C%2B%2B-O(1)-space.

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM