# 251 Flatten 2D Vector
[
[1,2],
[3],
[4,5,6]
]
把2D vector攤平,變成
[1,2,3,4,5,6]
由於剛修完Data structure,使用大量C++ STL,對C++的vector iterator還蠻熟悉的,
followup要我們只用C++ iterator或java iterator實作,我想應該是沒問題。
和一般iterator一樣,要實作constructor, next, hasNext三個function。
idea:
用兩個iterator,一個是在2d vector上跑,另一個在1d vector上跑,另外,當然需要把input 2d vector存起來。code(C++):
實作時遇到的問題第一個問題是vec_itr++要在next還是hasNext,如果寫在hasNext,會跳過第一個元素,改寫到next就好了。
第二個問題是第一行comment寫的edge case,在hasNext裡面處理掉了,上次寫iterator也是有卡在這種空input的edge case,下次要更注意!//edge case: [], [[],[],[]] class Vector2D { public: vector<vector<int>> vector2d; vector<vector<int>>::iterator vec2d_itr; vector<int>::iterator vec_itr; Vector2D(vector<vector<int>>& vec2d) { vector2d = vec2d; vec2d_itr = vector2d.begin(); if(vec2d_itr != vector2d.end()) vec_itr = (*vec2d_itr).begin(); } int next() { int res = (*vec_itr); vec_itr++; return res; } bool hasNext() { if(vector2d.size() == 0) return false; //current subarray still has element left. if(vec_itr != (*vec2d_itr).end()){ return true; } //move to next valid subarray vec2d_itr++; for(; vec2d_itr != vector2d.end(); vec2d_itr++){ vec_itr = (*vec2d_itr).begin(); if(vec_itr != (*vec2d_itr).end()) return true; } return false; } }; /** * Your Vector2D object will be instantiated and called as such: * Vector2D i(vec2d); * while (i.hasNext()) cout << i.next(); */
後來看了別人的解法,發現不用存整個2d vector,只要存begin和end就好了。
然後有些人會在next裡面呼叫hasNext,但我不太喜歡這種寫法,
覺的hasNext應該是要讓使用者call,call完後next就可以保證印出正確的值這樣比較合理。
但我的主要面試語言是Java,所以等等需要再寫一下java的版本,順便把java的iterator熟悉一下。
code(Java):
C++的iterator是用begin()和end()表示iteration的開始和結束,iterator的值不可能是null。而Java的iterator沒有這種東西,只有next()跟hasNext()而已,iterator在沒有initialize的時候是null。//用兩個iterator,一個是在2d vector上跑,另一個在1d vector上跑 public class Vector2D implements Iterator<Integer> { private Iterator<List<Integer>> list2d_itr; private Iterator<Integer> list_itr; public Vector2D(List<List<Integer>> vec2d) { //check the size of 2d list if(vec2d.size() == 0 || vec2d == null) return; //add an iterator to 2d list list2d_itr = vec2d.iterator(); //we have already checked that 2d list has at least 1 sublist, so assign an iterator to the first sublist. list_itr = list2d_itr.next().iterator(); } @Override public Integer next() { return list_itr.next(); } @Override public boolean hasNext() { if(list2d_itr == null) return false; //the current sublist still has element left if(list_itr.hasNext()){ return true; } //move to the next valid sublist while(list2d_itr.hasNext()){ list_itr = list2d_itr.next().iterator(); if(list_itr.hasNext()){ return true; } } return false; } } /** * Your Vector2D object will be instantiated and called as such: * Vector2D i = new Vector2D(vec2d); * while (i.hasNext()) v[f()] = i.next(); */