Buttercola: Airbnb: 2D Iterator with remove()
Implement a 2D iterator, with method next(), hasNext() and remove().
Understand the problem:
The question is close to the Leetcode Flatten 2D iterator. The only thing needs to take care is the remove() method.
According to the definition of the remove(),
Removes from the underlying collection the last element returned by this iterator (optional operation). This method can be called only once per call to next(). The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.
So the remove() method actually removes the element returned from the next().
ArrayList<ArrayList<Integer>> array;
int index_row;
int index_col;
public MyIterator(ArrayList<ArrayList<Integer>> array){
this.array = array;
index_row = 0;
index_col = 0;
}
public Boolean hasNext(){
// no more row
if(index_row >= array.size()){
return false;
}
// last row and last element in that row
if( (index_row == array.size()-1) && (index_col == array.get(index_row).size()) ){
return false;
}
return true;
}
public int next(){
int num = -1;
if(this.hasNext()){
num = array.get(index_row).get(index_col);
index_col += 1;
}
// promote to next row
if(index_col >= array.get(index_row).size()){
index_col = 0;
index_row += 1;
}
// empty row
if( array.get(index_row).size() < 1){
index_row += 1;
}
return num;
}
public void remove(){
int lastRow;
int lastCol;
// last element is on the upper row last element
if(index_col == 0){
lastRow = index_row - 1;
lastCol = array.get(lastRow).size()-1;
}else{
lastCol = index_col - 1;
lastRow = index_row;
//update current index;
index_col = index_col - 1;
}
if(array.get(lastRow).size() == 0){
lastRow -= 1;
}
// remove element
array.get(lastRow).remove(lastCol);
}
http://elise.co.nf/?p=620
https://github.com/jxr041100/system_design/blob/master/Airbnb:%202D%20Iterator%20with%20remove()
Implement a 2D iterator, with method next(), hasNext() and remove().
Understand the problem:
The question is close to the Leetcode Flatten 2D iterator. The only thing needs to take care is the remove() method.
According to the definition of the remove(),
Removes from the underlying collection the last element returned by this iterator (optional operation). This method can be called only once per call to next(). The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.
So the remove() method actually removes the element returned from the next().
To safely remove from a collection while iterating over it you should use an Iterator.
Not good implementation:
Not good implementation:
private
List<List<Integer>> array;
private
int
rowId;
private
int
colId;
private
int
numRows;
public
Solution(List<List<Integer>> array) {
this
.array = array;
rowId =
0
;
colId =
0
;
numRows = array.size();
}
public
boolean
hasNext() {
if
(array ==
null
|| array.isEmpty()) {
return
false
;
}
while
(rowId < numRows && (array.get(rowId) ==
null
||
array.get(rowId).isEmpty())) {
rowId++;
}
return
rowId < numRows;
}
public
int
next() {
int
ret = array.get(rowId).get(colId);
colId++;
if
(colId == array.get(rowId).size()) {
rowId++;
colId =
0
;
}
return
ret;
}
public
void
remove() {
List<Integer> listToRemove;
int
rowToRemove;
int
colToRemove;
// Case 1: if the element to remove is the last element of the row
if
(colId ==
0
) {
rowToRemove = rowId -
1
;
listToRemove = array.get(rowToRemove);
colToRemove = listToRemove.size() -
1
;
listToRemove.remove(colToRemove);
}
else
{
// Case 2: the element to remove is not the last element
rowToRemove = rowId;
listToRemove = array.get(rowToRemove);
colToRemove = colId -
1
;
listToRemove.remove(colToRemove);
}
// If the list to remove has only one element
if
(listToRemove.isEmpty()) {
array.remove(listToRemove);
rowId--;
}
// Update the colId
if
(colId !=
0
) {
colId--;
}
}
how ArrayList iterator is implemented and here's the code:
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
https://github.com/jxr041100/system_design/blob/master/Airbnb:%202D%20Iterator%20with%20remove()ArrayList<ArrayList<Integer>> array;
int index_row;
int index_col;
public MyIterator(ArrayList<ArrayList<Integer>> array){
this.array = array;
index_row = 0;
index_col = 0;
}
public Boolean hasNext(){
// no more row
if(index_row >= array.size()){
return false;
}
// last row and last element in that row
if( (index_row == array.size()-1) && (index_col == array.get(index_row).size()) ){
return false;
}
return true;
}
public int next(){
int num = -1;
if(this.hasNext()){
num = array.get(index_row).get(index_col);
index_col += 1;
}
// promote to next row
if(index_col >= array.get(index_row).size()){
index_col = 0;
index_row += 1;
}
// empty row
if( array.get(index_row).size() < 1){
index_row += 1;
}
return num;
}
public void remove(){
int lastRow;
int lastCol;
// last element is on the upper row last element
if(index_col == 0){
lastRow = index_row - 1;
lastCol = array.get(lastRow).size()-1;
}else{
lastCol = index_col - 1;
lastRow = index_row;
//update current index;
index_col = index_col - 1;
}
if(array.get(lastRow).size() == 0){
lastRow -= 1;
}
// remove element
array.get(lastRow).remove(lastCol);
}
http://elise.co.nf/?p=620
https://github.com/jxr041100/system_design/blob/master/Airbnb:%202D%20Iterator%20with%20remove()
实现二维数组的迭代器,加上remove操作
class Vector2D {
private:
vector<vector<int> >::iterator row, iBegin, iEnd;
vector<int>::iterator col;
public:
Vector2D(vector<vector<int> > &nums) {
row = nums.begin();
iBegin = nums.begin();
iEnd = nums.end();
if (!nums.empty()) col = row->begin();
}
int next() {
if (hasNext()) {
int val = *col;
col++;
return val;
}
throw "It's empty already!";
}
bool hasNext() {
while (row != iEnd && col == row->end()) {
++row;
if(row != iEnd)
col = row->begin();
}
return row != iEnd;
}
void remove() {
if (col == row->begin()) {
auto pre = prev(row);
while (pre != iBegin && (*pre).empty())
pre = prev(pre);
if (!(*pre).empty()) {
(*pre).erase(prev((*pre).end()));
} else {
throw "Should call next() first!";
}
} else {
(*row).erase(prev(col));
col--;
}
}
Read full article from Buttercola: Airbnb: 2D Iterator with remove()