[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:
- 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.
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函数即为取出当前位置元素。
Java:one iterator
public class Vector2D { List<Iterator<Integer>> its; int curr = 0; public Vector2D(List<List<Integer>> vec2d) { this.its = new ArrayList<Iterator<Integer>>(); for(List<Integer> l : vec2d){ // 只将非空的迭代器加入数组 if(l.size() > 0){ this.its.add(l.iterator()); } } } public int next() { Integer res = its.get(curr).next(); // 如果该迭代器用完了,换到下一个 if(!its.get(curr).hasNext()){ curr++; } return res; } public boolean hasNext() { return curr < its.size() && its.get(curr).hasNext(); } }
Java: two iterator
public class Vector2D { Iterator<List<Integer>> it; Iterator<Integer> curr; public Vector2D(List<List<Integer>> vec2d) { it = vec2d.iterator(); } public int next() { hasNext(); return curr.next(); } public boolean hasNext() { // 当前列表的迭代器为空,或者当前迭代器中没有下一个值时,需要更新为下一个迭代器 while((curr == null || !curr.hasNext()) && it.hasNext()){ curr = it.next().iterator(); } return curr != null && curr.hasNext(); } }
Java:
public class Vector2D { private List<List<Integer>> vec2d; private int rowId; private int colId; private int numRows; public Vector2D(List<List<Integer>> vec2d) { this.vec2d = vec2d; rowId = 0; colId = 0; numRows = vec2d.size(); } public int next() { int ans = 0; if (colId < vec2d.get(rowId).size()) { ans = vec2d.get(rowId).get(colId); } colId++; if (colId == vec2d.get(rowId).size()) { colId = 0; rowId++; } return ans; } public boolean hasNext() { while (rowId < numRows && (vec2d.get(rowId) == null || vec2d.get(rowId).isEmpty())) { rowId++; } return vec2d != null && !vec2d.isEmpty() && rowId < numRows; } }
Java: Followup: As an added challenge, try to code it using only iterators in C++ or iterators in Java.
public class Vector2D { private Iterator<List<Integer>>outerIterator; private Iterator<Integer> innerIterator; public Vector2D(List<List<Integer>> vec2d) { outerIterator = vec2d.iterator(); innerIterator = Collections.emptyIterator(); } public int next() { return innerIterator.next(); } public boolean hasNext() { if (innerIterator.hasNext()) { return true; } if (!outerIterator.hasNext()) { return false; } innerIterator = outerIterator.next().iterator(); return hasNext(); } } /** * 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): # @param vec2d {List[List[int]]} def __init__(self, vec2d): # Initialize your data structure here self.row, self.col, self.vec2d = 0, 0, vec2d # @return {int} a next element def next(self): # Write your code here self.col += 1 return self.vec2d[self.row][self.col - 1] # @return {boolean} true if it has next element # or false def hasNext(self): # Write your code here while self.row < len(self.vec2d) and \ self.col >= len(self.vec2d[self.row]): self.row, self.col = self.row + 1, 0 return self.row < len(self.vec2d) # Your Vector2D object will be instantiated and called as such: # i, v = Vector2D(vec2d), [] # while i.hasNext(): v.append(i.next())
C++:
class Vector2D { public: Vector2D(vector<vector<int>>& vec2d) { // Initialize your data structure here begin = vec2d.begin(); end = vec2d.end(); pos = 0; } int next() { // Write your code here hasNext(); return (*begin)[pos++]; } bool hasNext() { // Write your code here while (begin != end && pos == (*begin).size()) begin++, pos = 0; return begin != end; } private: vector<vector<int>>::iterator begin, end; int pos; }; /** * Your Vector2D object will be instantiated and called as such: * Vector2D i(vec2d); * while (i.hasNext()) cout << i.next(); */
类似题目:
[LeetCode] 341. Flatten Nested List Iterator 压平嵌套链表迭代器
All LeetCode Questions List 题目汇总