- Flatten 2D Vector
Implement an iterator to flatten a 2d vector.
Example
Example 1:
Input:[[1,2],[3],[4,5,6]]
Output:[1,2,3,4,5,6]
Example 2:
Input:[[7,9],[5]]
Output:[7,9,5]
注意这题不能用一个2D vector的copy,不然空间不满足要求。
解法1:利用C++的iterator
这题学到了很多iterator的知识。
- 一维和二维vector都有iterator,一维vector的iterator就好比指向每个元素的指针,二维vector的iterator就好比指向其中每个一维vector的指针。
- 空的一维和二维vector的begin()和end()相等。
- *(iter++)先返回*iter,然后iter++。
跟*(i++)一回事。 - iter像指针,但不能与指针比较。一个未初始化的iter不能与NULL比较。如果非要初始化,可将其初始化为对应container的end()。
即vector a = {1,2,3,4,5};
vector::iterator iter = a.end();
代码如下:
class Vector2D {
public:
Vector2D(vector<vector<int>>& vec2d) {
begin = vec2d.begin();
end = vec2d.end();
if (begin != end) iter = (*begin).begin(); //注意如果begin是空指针,那么(*begin).begin()就出错。必须加if检查。
}
int next() {
hasNext();
return *(iter++);
}
bool hasNext() {
while(begin != end && (iter == (*begin).end())) {
begin++;
iter = (*begin).begin();
}
return begin != end;
}
private:
vector<vector<int>>::iterator begin, end;
vector<int>::iterator iter;
};
/**
* Your Vector2D object will be instantiated and called as such:
* Vector2D i(vec2d);
* while (i.hasNext()) cout << i.next();
*/
二刷:
class Vector2D {
public:
Vector2D(vector<vector<int>>& vec2d) {
rowIter = vec2d.begin();
vec2dEnd = vec2d.end();
if (rowIter != vec2dEnd) colIter = rowIter->begin();
}
int next() {
hasNext();
return *colIter++;
}
bool hasNext() {
while (rowIter != vec2dEnd && colIter == rowIter->end()) {
rowIter++;
colIter = rowIter->begin();
}
return rowIter != vec2dEnd;
}
private:
vector<vector<int>>::iterator rowIter, vec2dEnd;
vector<int>::iterator colIter;
};
三刷: 代码不是很精炼。注意测试程序会在每次call next()之前调用hasNext()。如果hasNext()返回false,测试程序就不会前进了。
class Vector2D {
public:
Vector2D(vector<vector<int>>& vec2d) : data(vec2d) {
// Initialize your data structure here
x = 0;
y = 0;
}
int next() {
if (hasNext()) {
int res = data[x][y];
y++;
return res;
}
}
bool hasNext() {
if (x == data.size()) return false;
if (y == data[x].size()) {
y = 0;
x++;
}
if (x == data.size() - 1 && data[x].size() == 0) return false;
return x < data.size();
}
private:
vector<vector<int>> data;
int x, y;
};
/**
* Your Vector2D object will be instantiated and called as such:
* Vector2D i(vec2d);
* while (i.hasNext()) cout << i.next();
*/
四刷:参考的网上的做法。先把vec2d拷贝到vec1d。注意关键是当vec2d[i]为空时,是不会copy任何东西到vec1d的,这样就避开了vec2d里面的空数组的坑。
vec1d.insert(vec1d.end(), vec2d[i].begin(), vec2d[i].end());
class Vector2D {
public:
Vector2D(vector<vector<int>>& vec2d) {
for (int i = 0; i < vec2d.size(); i++) {
vec1d.insert(vec1d.end(), vec2d[i].begin(), vec2d[i].end());
}
}
int next() {
return vec1d[index++];
}
bool hasNext() {
return index < vec1d.size();
}
private:
vector<int> vec1d;
int index = 0;
};