leetcode 230. Kth Smallest Element in a BST

257 篇文章 17 订阅

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Note: 
You may assume k is always valid, 1 ? k ? BST's total elements.

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?


我们可以趁这个问题来复习一下二叉搜索树:

结构特点

二叉搜索树的特点是,小的值在左边,大的值在右边,即

比如:

这样的结构有一个好处是很容易获得最大值(Maximum)、最小值(minimum)、某元素的前驱(Precursor)、某元素的后继(Successor)。

最大值:树的最右节点。

最小值:树的最左节点。

某元素前驱:左子树的最右。

某元素的后继:右子树的最左。


根据以上特性,我们可以知道:由于小的节点在左边,大的节点在右边,因此使用中序(in-order)遍历可以方便的得到一个sorted list。所以这道题可以使用中序遍历,直到遍历了第k次。

public int kthSmallest(TreeNode root, int k) {
	List<Integer> list=new ArrayList<Integer>();
	traversal(root, k, list);
	return list.get(k-1);
}

public void traversal(TreeNode node,int k,List<Integer> list){
	if(node==null||list.size()==k){
		return;
	}
	traversal(node.left, k, list);
	list.add(node.val);
	if(list.size()<k){
		traversal(node.right, k, list);
	}			
}

大神使用了迭代来进行中根遍历。
 public int kthSmallest(TreeNode root, int k) {
     Stack<TreeNode> stack = new Stack<TreeNode>();
     TreeNode p = root;
     int count = 0;
     
     while(!stack.isEmpty() || p != null) {
         if(p != null) {
             stack.push(p);  // Just like recursion
             p = p.left;   
             
         } else {
            TreeNode node = stack.pop();
            if(++count == k) return node.val; 
            p = node.right;
         }
     }
     
     return Integer.MIN_VALUE;
 }

另外还有大神用了二分搜索的方法,时间复杂度不及上面两种方法,但是也不失为解决二叉搜索树问题的一个好办法。

public int kthSmallest(TreeNode root, int k) {
    int count = countNodes(root.left); //count得到:root左子树结点个数
    if (count >= k) {  //如果count>=k,说明第k个树一定在左子树里
        return kthSmallest(root.left, k);
    } 
    else if (count + 1 < k) {  //如果count+1<k,其中 1代表root本身,那说明第k个数在右子树里
        return kthSmallest(root.right, k-1-count); // 1 is counted as current node
    }
    
    return root.val;  //这是count+1=k的情况
}

public int countNodes(TreeNode n) {
    if (n == null) return 0;
    
    return 1 + countNodes(n.left) + countNodes(n.right);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值