problems: add flatten nested list iterator
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
a71684d500
commit
5dd35539a5
1 changed files with 118 additions and 0 deletions
118
problems/flatten-nested-list-iterator.java
Normal file
118
problems/flatten-nested-list-iterator.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
import java.util.ArrayDeque;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
interface NestedInteger {
|
||||
// @return true if this NestedInteger holds a single integer, rather than a nested list.
|
||||
public boolean isInteger();
|
||||
// @return the single integer that this NestedInteger holds, if it holds a single integer
|
||||
// Return null if this NestedInteger holds a nested list
|
||||
public Integer getInteger();
|
||||
// @return the nested list that this NestedInteger holds, if it holds a nested list
|
||||
// Return empty list if this NestedInteger holds a single integer
|
||||
public List<NestedInteger> getList();
|
||||
}
|
||||
|
||||
/**
|
||||
* // This is the interface that allows for creating nested lists.
|
||||
* // You should not implement it, or speculate about its implementation
|
||||
* public interface NestedInteger {
|
||||
*
|
||||
* // @return true if this NestedInteger holds a single integer, rather than a nested list.
|
||||
* public boolean isInteger();
|
||||
*
|
||||
* // @return the single integer that this NestedInteger holds, if it holds a single integer
|
||||
* // Return null if this NestedInteger holds a nested list
|
||||
* public Integer getInteger();
|
||||
*
|
||||
* // @return the nested list that this NestedInteger holds, if it holds a nested list
|
||||
* // Return empty list if this NestedInteger holds a single integer
|
||||
* public List<NestedInteger> getList();
|
||||
* }
|
||||
*/
|
||||
class NestedIterator implements Iterator<Integer> {
|
||||
|
||||
private class DFSEntry {
|
||||
private List<NestedInteger> it;
|
||||
private int i = 0;
|
||||
|
||||
public DFSEntry(List<NestedInteger> it) {
|
||||
this.it = it;
|
||||
}
|
||||
|
||||
private int size() {
|
||||
return it.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return i >= size();
|
||||
}
|
||||
|
||||
public NestedInteger at() {
|
||||
return it.get(i);
|
||||
}
|
||||
|
||||
public void advance() {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayDeque<DFSEntry> stack = new ArrayDeque<>();
|
||||
|
||||
public NestedIterator(List<NestedInteger> nestedList) {
|
||||
stack.addLast(new DFSEntry(nestedList));
|
||||
findNext();
|
||||
}
|
||||
|
||||
private DFSEntry top() {
|
||||
return stack.peekLast();
|
||||
}
|
||||
|
||||
// Performs one „iteration“ of the DFS algorithm
|
||||
private void findNext() {
|
||||
while (!stack.isEmpty()) {
|
||||
// We ran out of successors
|
||||
if (top().isEmpty()) {
|
||||
stack.removeLast();
|
||||
|
||||
// Advance the parent of the removed list
|
||||
if (top() != null) {
|
||||
top().advance();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Base: we have found an integer
|
||||
if (top().at().isInteger()) {
|
||||
return;
|
||||
}
|
||||
|
||||
stack.addLast(new DFSEntry(top().at().getList()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
DFSEntry top = stack.getLast();
|
||||
Integer e = top.at().getInteger();
|
||||
|
||||
// Find next integer in the nested list
|
||||
top.advance();
|
||||
findNext();
|
||||
|
||||
// Return the popped element
|
||||
return e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !stack.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Your NestedIterator object will be instantiated and called as such:
|
||||
* NestedIterator i = new NestedIterator(nestedList);
|
||||
* while (i.hasNext()) v[f()] = i.next();
|
||||
*/
|
Loading…
Reference in a new issue