this problem is very similar to LC251 flatten 2d vector
the difference is, LC251 the input is strictly 2D array.
and LC341 the input is nD array.
But both of them need us to design a data structure that have two methods: next() and hasNext().

although all the similarities between those two problems, the data structure uses for them is different,
LC251 uses a 2D array and two pointers.
LC341 will use a stack.

and LC341, the nested element is a new interger, called NextInteger, and it has three methods to use:
isInteger()
getInteger() // @return the single integer that this NestedInteger holds, if it holds a single integer

  •             // Return null if this NestedInteger holds a nested list
    

getList() // @return the nested list that this NestedInteger holds, if it holds a nested list

  •       // Return null if this NestedInteger holds a single integer
    

it’s really hard to really understand those three given methods without peeking on the final solution, and the code is pretty clear, and after read the solution,

public class NestedIterator implements Iterator<Integer> {

    Stack<NestedInteger> stack;
    
    public NestedIterator(List<NestedInteger> nestedList) {
        //if (nestedList == null || nestedList.size() == 0) return;
        stack = new Stack();
        for (int i = nestedList.size() - 1; i >= 0; i--) { //push from the last one so we can pop it in order
            stack.push(nestedList.get(i));
        }
    }

    @Override
    public Integer next() {
        return stack.pop().getInteger();
    }

    @Override
    public boolean hasNext() { //has next is like a deserializer
        while (!stack.isEmpty()) {
            NestedInteger cur = stack.peek();
            if (cur.isInteger()) { //if it is an integer
                return true; //just return true
            }
            stack.pop(); //or else, it is a nested integer, pop it and deserilized it
            for (int i = cur.getList().size() - 1; i >= 0; i--) { //
                stack.push(cur.getList().get(i)); //it's a deserilized and push back process
            }
        }
        return false;
    }
}

when I take a look at the

for (int i = nestedList.size() - 1; i >= 0; i--) { //push from the last one so we can pop it in order
            stack.push(nestedList.get(i));
        }

I thought, why bother? can;t we just use queue and for loop from 0 to size as a normal person?
but no, after you changed all stack to queue, the solution is not right.
after detailed checking, I found the reason why not working as I expected:
in hasNext() method, when we find out that cur is not a NestedInteger, if not, then we deserilized it and push it back, pay attention to the push back part, if we are using stack, if we push back, then next time the stack pop(), it will pop out those things we just pushed. but if we are using a regular queue, then when we poll it and offer it back, it will added to the end of queue and next round will not be called out. so if we do want to use a queue here, at least we should use a deque.