[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函数即为取出当前位置元素。

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 题目汇总

 

posted @ 2018-03-16 07:20  轻风舞动  阅读(1119)  评论(0编辑  收藏  举报