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.
思路1:先用list把 所有size不为0的Iterator装起来,然后每次取得了next的值的时候,判断一下当前的Iterator是否还有值,如果没有,就跳到下一个Iterator。
public class Vector2D implements Iterator<Integer> {
List<Iterator<Integer>> list = new ArrayList<Iterator<Integer>>();
int cur = 0;
public Vector2D(List<List<Integer>> vec2d) {
for(List<Integer> l : vec2d){
if(l.size()>0){
list.add(l.iterator());
}
}
}
@Override
public Integer next() {
int value = list.get(cur).next();
if(!list.get(cur).hasNext()){
cur++;
}
return value;
}
@Override
public boolean hasNext() {
return cur < list.size() && list.get(cur).hasNext();
}
}
/**
* Your Vector2D object will be instantiated and called as such:
* Vector2D i = new Vector2D(vec2d);
* while (i.hasNext()) v[f()] = i.next();
*/
这题,题目改成int[][] 了,这里用i,j来表示,双指针; 当i < v.length && j == v[i].length的时候,move到下一个;
class Vector2D {
int i = 0; int j = 0;
int[][] vec;
public Vector2D(int[][] vec) {
this.vec = vec;
}
public int next() {
if(hasNext()) {
return vec[i][j++];
} else {
return -1;
}
}
public boolean hasNext() {
while(i < vec.length && j == vec[i].length) {
i++;
j = 0;
}
return i < vec.length;
}
}
/**
* Your Vector2D object will be instantiated and called as such:
* Vector2D obj = new Vector2D(vec);
* int param_1 = obj.next();
* boolean param_2 = obj.hasNext();
*/