题目:
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:
- How many variables do you need to keep track?
- Two variables is all you need. Try with
x
andy
. - Beware of empty rows. It could be the first few rows.
- To write correct code, think about the invariant to maintain. What is it?
- The invariant is
x
andy
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? - Not sure? Think about how you would implement
hasNext()
. Which is more complex? - Common logic in two different places should be refactored into a common method.
C++版:
class Vector2D {
public:
Vector2D(vector<vector<int>>& vec2d) {
row = vec2d.begin();
end = vec2d.end();
while(row != end) {
if((*row).size() > 0) {
col = (*row).begin();
break;
}
row++;
}
}
int next() {
int lastValue = *col;
col++;
return lastValue;
}
bool hasNext() {
if(row == end)
return false;
if(col != (*row).end()) {
return true;
} else {
while(row != end) {
row++;
if(row != end && (*row).size() != 0) {
col = (*row).begin();
return true;
}
}
return false;
}
}
private:
vector<vector<int>>::iterator row, end;
vector<int>::iterator col;
};
/**
* Your Vector2D object will be instantiated and called as such:
* Vector2D i(vec2d);
* while (i.hasNext()) cout << i.next();
*/
Java版:
class Vector2D {
public Vector2D(List<List<Integer>> vec2d) {
row = vec2d.iterator();
if(row.hasNext())
col = row.next().iterator();
}
public int next() {
int lastValue = col.next();
return lastValue;
}
public boolean hasNext() {
if(col == null) {
return false;
}
if(col.hasNext()) {
return true;
} else {
while(row.hasNext()) {
col = row.next().iterator();
if(col.hasNext())
return true;
}
return false;
}
}
private Iterator<List<Integer>> row = null;
private Iterator<Integer> col = null;
}
/**
* Your Vector2D object will be instantiated and called as such:
* Vector2D i = new Vector2D(vec2d);
* while (i.hasNext()) v[f()] = i.next();
*/
Python版:
class Vector2D(object):
def __init__(self, vec2d):
"""
Initialize your data structure here.
:type vec2d: List[List[int]]
"""
self.vec = vec2d
self.row = 0
self.col = 0
i = 0
while self.row != len(self.vec):
if len(self.vec[self.row]) != 0:
self.col = 0
break
self.row += 1
def next(self):
"""
:rtype: int
"""
ret = self.vec[self.row][self.col]
self.col += 1
return ret
def hasNext(self):
"""
:rtype: bool
"""
if self.row == len(self.vec):
return False
if self.col != len(self.vec[self.row]):
return True
else:
self.row += 1
while self.row != len(self.vec):
if len(self.vec[self.row]) != 0:
self.col = 0
return True
self.row += 1
return False
# Your Vector2D object will be instantiated and called as such:
# i, v = Vector2D(vec2d), []
# while i.hasNext(): v.append(i.next())