LeetCode 251 - Flatten 2D Vector


LeetCode: Flatten 2D Vector | CrazyEgg
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.
https://segmentfault.com/a/1190000003791233
数组法
时间 O(N) 空间 O(1)
用一个数组表示每个List的迭代器,然后再记录一个变量,用来表示当前用到了第几个迭代器。
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();
    }
}
X. 双迭代器法
时间 O(N) 空间 O(1)
思路
维护两个迭代器:一个是输入的List<List<Integer>>的迭代器,它负责遍历List<Integer>的迭代器。另一个则是List<Integer>的迭代器,它负责记录当前到哪一个List的迭代器了。每次next时,我们先调用一下hasNext,确保当前List的迭代器有下一个值。
public class Vector2D {

    Iterator<List<Integer>> it;
    Iterator<Integer> curr;
    
    public Vector2D(List<List<Integer>> vec2d) {
        it = vec2d.iterator();
    }

    public int next() {
        hasNext(); // if false, throw NoSuchElementException
        return curr.next();
    }

    public boolean hasNext() {
        // 当前列表的迭代器为空,或者当前迭代器中没有下一个值时,需要更新为下一个迭代器
        while((curr == null || !curr.hasNext()) && it.hasNext()){
            curr = it.next().iterator();
        }
        return curr != null && curr.hasNext();
    }
}
http://buttercola.blogspot.com/2015/08/leetcode-flatten-2d-vector.html
The question itself is very easy to solve. Just several corner cases need to think of:
  -- What if the 2d vector contains empty arrays, e.g. [ ], [ ], 1 2 3 ? In this case, the next() should not output anything, but the return type is int. There the hasNext() should be more complicated in which it handles this situation. 
  -- What if the 2d vector itself is empty? Again, handle it in hasNext() 
public class Vector2D {
    private Iterator<List<Integer>> outer;
    private Iterator<Integer> inner;
    public Vector2D(List<List<Integer>> vec2d) {
        outer = vec2d.iterator();
        inner = Collections.emptyIterator(); //inner = outer.iterator(); wrong: if outer is null, then exception
    }
    public int next() { // call hasNext() first
        return inner.next();
    }
    public boolean hasNext() {
        if (inner.hasNext()) {
            return true;
        }
        if (!outer.hasNext()) {
            return false;
        }
        inner = outer.next().iterator();
        while(!inner.hasNext() && outer.hasNext()) {
            inner = outer.next().iterator();
        }
        return inner.hasNext();
    }
}

https://leetcode.com/discuss/50292/7-9-lines-added-java-and-c-o-1-space
public class Vector2D { private Iterator<List<Integer>> i; private Iterator<Integer> j; public Vector2D(List<List<Integer>> vec2d) { i = vec2d.iterator(); } public int next() { hasNext(); return j.next(); } public boolean hasNext() { while ((j == null || !j.hasNext()) && i.hasNext()) j = i.next().iterator(); return j != null && j.hasNext(); } }
http://leetcode.tgic.me/flatten-2d-vector/index.html
 3     Iterator<List<Integer>> outterIter;
 4     Iterator<Integer> innerIter = Collections.emptyIterator();
 5 
 6     public Vector2D(List<List<Integer>> vec2d) {
 7         outterIter = vec2d.iterator();
 8     }
 9 
10     public int next() {
11         return innerIter.next();
12     }
14     public boolean hasNext() {
15         if(innerIter.hasNext()){
16             return true;
17         }
18         // while to skip empty collection
19         if(!outterIter.hasNext()){
20             return false;
21         }
22 
23         innerIter = outterIter.next().iterator();
24 
25         return hasNext();
26     }

https://leetcode.com/discuss/50356/my-concise-java-solution
private List<List<Integer>> vec2d; private int index1 = 0; private int index2 = 0; private int max_row = 0; public Vector2D(List<List<Integer>> vec2d) { this.vec2d = vec2d; max_row = vec2d.size(); while(index1 < max_row && vec2d.get(index1).size() == 0) { index1++; } } public int next() { return vec2d.get(index1).get(index2++); } public boolean hasNext() { if (index1 >= max_row) { return false; } if (index2 < vec2d.get(index1).size()) { return true; } while(++index1 < max_row) { if (vec2d.get(index1).size() > 0) { index2 = 0; return true; } } return false; }
https://leetcode.com/discuss/57984/simple-and-short-java-solution-with-iterator
  • Put all iterator in a queue
  • Keep track of the current iterator
  • Check hasNext() and next() of current
https://leetcode.com/discuss/73910/java-iterator-solution-explained
I first hold the 2D List inside a Iterator of List this allows me to operate on the subsequent list once needed. I then remove the first list from the 2D List and store as row which is evaluated when next() & hasNext() are called. I then want to ensure row iterator is pointing to a none empty list so i call the getNextRow() method. next() and hashNext() are now very simple.next() returns the next element of the current list then ensures row isn't empty. hasNext()checks row isn't null and has a next value.
public class Vector2D { Iterator<List<Integer>> itrs; Iterator<Integer> row; public Vector2D(List<List<Integer>> vec2d) { if(vec2d == null || vec2d.size() == 0) return; itrs = vec2d.iterator(); row = itrs.next().iterator(); getNextRow(); } private void getNextRow(){ while(!row.hasNext() && itrs.hasNext()) row = itrs.next().iterator(); } public int next() { int next = row.next(); getNextRow(); return next; } public boolean hasNext() { return row != null && row.hasNext(); } }
http://likemyblogger.blogspot.com/2015/08/leetcode-251-flatten-2d-vector.html
    vector<vector<int>>::iterator row_it, row_end;
    vector<int>::iterator col_it;
public:
    Vector2D(vector<vector<int>>& vec2d) {
        row_it = vec2d.begin();
        row_end = vec2d.end();
        while(row_it!=row_end && row_it->empty()) row_it++;
        if(row_it!=row_end) col_it = row_it->begin();
    }
    int next() {
        int v = *col_it;
        col_it++;
        if(col_it==row_it->end()){
            row_it++;
            while(row_it!=row_end && row_it->empty()) row_it++;
            if(row_it!=row_end) col_it = row_it->begin();
        }
        return v;
    }
    bool hasNext() {
       if(row_it==row_end) return false;
       return true;
    }
X. Brute Force
https://leetcode.com/discuss/50677/concise-java-solution
    private int[] arrCounters;
    private int counter = 0;

    public Vector2D(List<List<Integer>> vec2d) {
        int cnt = 0;
        if (vec2d == null) {
            arrCounters = new int[0];
        } else {

            for (List<Integer> l : vec2d) {
                cnt += (l == null) ? 0 : l.size();
            }
            arrCounters = new int[cnt];

            cnt = 0;
            for (List<Integer> l : vec2d) {
                for (int in : l) {
                    arrCounters[cnt++] = in;
                }
            }
        }
    }

    public int next() {
        int val = Integer.MIN_VALUE;
        if (counter < arrCounters.length) {
            val = arrCounters[counter];
        }
        counter++;
        return val;
    }

    public boolean hasNext() {
        return counter < arrCounters.length;
    }
http://www.cnblogs.com/grandyang/p/5209621.html

https://xuezhashuati.blogspot.com/2017/04/lintcode-601-flatten-2d-vector.html
因为是2D的vector,所以我们只需要2个index去定位数字:
一个定位sub list的位置,一个定位在sub list下具体元素的位置。
- Not good as the input may be a linkedlist
public class Vector2D implements Iterator<Integer> {

    private int ListIndex;
    private int ElementIndex;
    private List<List<Integer>> vec;
    public Vector2D(List<List<Integer>> vec2d) {
        // Initialize your data structure here
        ListIndex = 0;
        ElementIndex = 0;
        vec = vec2d;
    }

    @Override
    public Integer next() {
        hasNext();
        return vec.get(ListIndex).get(ElementIndex++);
    }

    @Override
    public boolean hasNext() {
        while (ListIndex < vec.size()) {
            if (ElementIndex < vec.get(ListIndex).size()) {
                return true;
            }
            else {
                ListIndex++;
                ElementIndex = 0;
            }
        }
        return false;
    }

    @Override
    public void remove() {}
}
http://www.1point3acres.com/bbs/thread-199481-1-1.html
Follow up: implement remove.

airbnb面试题汇总
2D itertaor + remove()
http://massivealgorithms.blogspot.com/2015/11/buttercola-airbnb-2d-iterator-with.html
Read full article from LeetCode: Flatten 2D Vector | CrazyEgg

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts