【Lintcode】86. Binary Search Tree Iterator

题目地址:

https://www.lintcode.com/problem/binary-search-tree-iterator/

给定一个BST,设计其中序遍历的iterator。

思路是模仿二叉树的非递归中序遍历。用一个节点指针cur来保存当前需要中序遍历的子树的根,然后用一个栈来模拟递归。当调用next()方法时,也就是要开始中序遍历cur这个子树,那么应当返回的当然是cur一路向左走到的最后一个节点node,并且下一个要中序遍历的子树就是node的右子树,所以将cur赋值为node的右子树的根;如果cur本身是null,说明以cur为右子树根的那棵子树遍历完了,也就意味着这棵子树也中序遍历完了,那么下一个要返回的节点应当是node的父亲节点,并且下一个要中序遍历的子树是node的父亲节点的右子树,所以将cur赋值为node父亲的右子树的根。显然hasNext()返回true说明还有节点没访问完,意味着要么接下来要访问的右子树cur不为空,要么cur的父亲这棵子树访问完后还有树根要访问,而这个树根就是栈顶。所以其返回true当且仅当cur不为null或者栈不空。代码如下:

import java.util.ArrayDeque;
import java.util.Deque;

public class BSTIterator {
    
    private Deque<TreeNode> stack;
    // cur存放的是接下来要中序遍历的子树的树根
    private TreeNode cur;
    
    /*
     * @param root: The root of binary tree.
     */
    public BSTIterator(TreeNode root) {
        // do intialization if necessary
        stack = new ArrayDeque<>();
        // 一开始要中序遍历的子树当然就是树本身,树根就是root
        cur = root;
    }
    
    /*
     * @return: True if there has next node, or false
     */
    public boolean hasNext() {
        // write your code here
        return cur != null || !stack.isEmpty();
    }
    
    /*
     * @return: return next node
     */
    public TreeNode next() {
        // write your code here
        // 如果接下来要遍历的子树非空,那么按照中序遍历的原则,应当返回其最左边的节点
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }

        // 下次调用next时,要遍历的子树的根应当是右子树根
        cur = stack.peek().right;
        return stack.pop();
    }
}

class TreeNode {
    int val;
    TreeNode left, right;
    
    TreeNode(int x) {
        val = x;
    }
}

hasNext()的时间复杂度 O ( 1 ) O(1) O(1)next()的时间复杂度是 O ( h ) O(h) O(h),均摊复杂度是 O ( 1 ) O(1) O(1);空间复杂度 O ( h ) O(h) O(h)

均摊复杂度 O ( 1 ) O(1) O(1)的理由是,每个节点都只会入栈出栈各一次,所以遍历完整棵树的复杂度是 O ( n ) O(n) O(n),而遍历完整棵树的操作次数是 n n n次,所以均摊下来每次操作时间 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值