Sequence Iterator
Flatten Iterator -> flatten a iterator of iterator
{1,2,3}, {}, {4}, {}, {5,6}} -> {1,2,3,4,5,6}
p1 p2 p3 p4 p5
public SequenceIterator implements Iterator<Integer> {
Iterator<Integer> inner ;
Iterator<Iterator<Integer>> out;
public SequenceIterator(Iterator<Iterator<Iterator>> out) {
//change this line to null
this.inner = null;
this.out = out;
}
public boolean hasNext() {
//point to next out ptr.
while(inner == null || !inner.hasNext() && it.hasNext()) {
inner = out.next();
}
return inner != null && inner.hasNext();
}
public Integer next() {
//first call hasNext()
if (!hasNext()) {
throw new NoSuchElementException();
}
return inner.next();
}
public void remove() {
throw UnSupportedOperationException();
}
}
Even Iterator
public class EvenIterator {
Iterator<Integer> it;
boolean moved;
public EvenIterator(Iterator<Integer> iter) {
this.it = iter;
this.moved = false;
}
public boolean hasNext() {
if (!moved) {
return it.hasNext();
}
moved = true;
if (it.hasNext()) {
it = it.next();
}
return it.hasNext();
}
public Integer next() {
if (hasNext()) {
moved = false;
return it.next();
}
return null;
}
}
Index Even iterator
when next(). go two steps instead of one.
{1,2,3,4,5} -> {1,3,5}
Solution 1: keep index counter.
Solution 2: keep boolean indicator.
public class EvenIterator {
Iterator<Integer> it = null;
boolean isMoved = false;
public EvenIterator(Iterator<Integer> it) {
it = iter;
}
public boolean hasNext() {
if(isMoved) {
return it.hasNext();
}
isMoved = true;
if(it.hasNext()) {
it.next();
}
return it.hasNext();
}
public Integer next() {
if(hasNext()) {
isMoved = false;
return it.next();
}
return null;
}
}
Element Even Iterator
only return element with even.
/*
Integer next() : return current element if exist
boolean hasNext() : proceed to next odd position
*/
public class EvenElementIterator {
int even;
Iterator<Integer> it;
public EvenElementIterator(Iterator<Integer> it) {
this.even = 1;
this.it = it;
}
public boolean hasNext() {
if (even % 2 == 0) {
return true;
}
while(it.hasNext()) {
even = it.next();
if (even % 2 == 0) {
return true;
}
}
return true;
}
public Integer next() {
if (hasNext()) {
int temp = even;
//this line is important
even = 1;
return temp;
}
throw NoSuchElementException();
}
}
ZigZag Iterator
Two iterator list
public class ZigZagTwo {
List<Iterator<Integer>> iters;
boolean atZero = true;
public ZigZagTwo(List<Iterator<Integer>> iters) {
this.atZero = true;
this.iters = iters;
}
public boolean hasNext() {
return iters.get(0) != null && iters.get(0).hasNext() ||iters.get(1) != null && iters.get(1).hasNext();
}
public Integer next() {
if(hasNext()) {
int ret = -1;
if (atZero) {
ret = iters.get(0).hasNext() ? iters.get(0).next() : iters.get(1).next();
atZero = false;
} else {
ret = iters.get(1).hasNext() ? iters.get(1).next() : iters.get(0).next();
atZero = true;
}
return ret;
}
throw NoSuchElementException();
}
}
ZigZag K
instead of maintaining a boolean value to indicate at one or two, we need an index to indicate cur index and somehow record whether we reach an end.
Implementation 1 : solution in docs
public class ZigZagK {
List<Iterator<Integer>> iters;
int index; //next position we are reaching
int lastIndex; //searching area just optimization
int lastAvaiIndex;
Iterator<Integer> cur; //element we are at now
public ZigZagK (List<Iterator<Integer>> iters) {
cur = null;
this.index = 0;
this.lastIndex = iters.size() - 1;
this.lastAvaiIndex = -1;
}
public boolean hasNext() {
while(cur == null || !cur.hasNext() && index <= lastIndex) {
cur = iters.get(index);
if (cur != null && cur.hasNext()) {
lastAvaiIndex = index;
}
index++;
if(index == lastIndex + 1) {
index = 0;
lastIndex = lastAvaiIndex;
lastAvaiIndex = -1;
}
}
return cur != null && cur.hasNext();
}
public Integer next() {
if (hasNext()) {
int ret = cur.next();
cur = null;
return ret;
}
throw NoSuchElementException();
}
}