【leetcode】341.扁平化嵌套列表迭代器 (递归,栈,java实现)

341. 扁平化嵌套列表迭代器

难度中等

给你一个嵌套的整型列表。请你设计一个迭代器,使其能够遍历这个整型列表中的所有整数。

列表中的每一项或者为一个整数,或者是另一个列表。其中列表的元素也可能是整数或是其他列表。

示例 1:

输入: [[1,1],2,[1,1]]
输出: [1,1,2,1,1]
解释: 通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,1,2,1,1]。

示例 2:

输入: [1,[4,[6]]]
输出: [1,4,6]
解释: 通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,4,6]。

递归的写法

这一题需要用到队列,在Java中实际上可以使用linkedlist来实现队列。
实现的方法是使用offer函数实现入队操作,用poll函数实现出队操作。

public class NestedIterator implements Iterator<Integer> {

    private Queue<Integer> list;

    public NestedIterator(List<NestedInteger> nestedList) {
        list = new LinkedList<>();
        dfs(nestedList);
    }

    private void dfs(List<NestedInteger> nestedList){

        if (nestedList == null) return;

        for (NestedInteger nestedInteger : nestedList) {
            if (nestedInteger.isInteger()) {
                list.offer(nestedInteger.getInteger());
            } else {
                dfs(nestedInteger.getList());
            }
        }

    }

    @Override
    public Integer next() {
        return list.poll();
    }

    @Override
    public boolean hasNext() {
        return list.size() > 0;
    }
}

栈的解法

栈的解法的思想是:
将栈顶元素作为当前活跃的元素,比如[[2, 1], 1, [2, 3]],最开始压入栈中,然后取出了第一个元素[2, 1],此时将这个元素压入栈中,成了栈顶元素,此时整个栈变成了[2,1], [1, [2, 3]],我们继续遍历栈顶元素,拿到了2,发现2不是一个迭代对象,所以将2作为next,并且原迭代器中删除2,然后跳出循环。

其实这个就是模拟递归的系统栈的一个思路,当遇到递归的时候,比如在上面碰到了[2,1],此时先将当前执行的[[2, 1], 1, [2, 3]][2,1]删除掉,然后将[2, 1]压入栈中,每次要执行的就是栈顶元素而已。

在Java中,LinkedList不仅可以模拟队列,还可以模拟栈。
比如元素1,2,3,4,5,按照栈的规则,输出应该是5,4,3,2,1,所以在LinkedList中我们使用offerFirst头插法,此时插入进去的就是5,4,3,2,1,然后我们使用pollFirst,即可从头节点获得输出5,4,3,2,1.

其中需要注意pollFirstpoll方法是一样的,它的意思更多的是给我们明确从头节点取值。可以参考Javadoc中的说明:

  • poll() : Retrieves and removes the head of the queue represented by this deque (in other words, the first element of this deque), or returns null if this deque is empty.
  • remove() : Return the head of this list, throws NoSuchElementException if this list is empty
  • pollFirst() is the same as poll().
  • pollLast() return the last element of this list, or null if this list is empty
  • removeFirst() is the same as remove()
public class NestedIterator implements Iterator<Integer> {

    private LinkedList<Iterator<NestedInteger>> stack;
    private Integer num;
    private boolean flag;

    public NestedIterator(List<NestedInteger> nestedList) {
        // 构造一个栈 栈顶元素存放的是当前活跃的列表
        stack = new LinkedList<>();
        stack.add(nestedList.iterator());
    }

    @Override
    public Integer next() {
        flag = false;
        return num;
    }

    @Override
    public boolean hasNext() {
        if (stack.isEmpty()) return false;
        // 取出栈顶活跃的迭代器
        while (!stack.isEmpty() && !flag) {
            // 取出栈顶元素
            Iterator<NestedInteger> iterator = stack.peekFirst();
            if (!iterator.hasNext()) {
                // 如果栈顶的迭代器已经是空了就出栈
                stack.pollFirst();
            } else {
                NestedInteger next = iterator.next();
                if (next == null) continue;
                if (next.isInteger()) {
                    num = next.getInteger();
                    flag = true;
                    iterator.remove();
                } else {
                    stack.offerFirst(next.getList().iterator());
                    iterator.remove();
                }
            }
        }

        return flag;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值