剑指offer 62. 二叉搜索树的第 k 个结点 & leetcode 精选top面试题 230. 二叉搜索树中第K小的元素...

 62. 二叉搜索树的第 k 个结点 & 230. 二叉搜索树中第K小的元素

题目描述

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4。

法一:中序遍历递归写法

 1 class Solution {
 2 
 3     public int i = 0;   // 表示当前是第几个结点
 4     public int val = -1;    // 记录第k个结点的值
 5 
 6     public int kthSmallest(TreeNode root, int k) {
 7         // 中序遍历被访问的第k个结点
 8         inOrder(root, k);
 9         return val;
10     }
11 
12     // 中序遍历树的所有结点
13     public void inOrder(TreeNode root, int k){
14         if(root != null && i < k){      // i 如果大于等于k则没必要继续遍历了
15             inOrder(root.left, k);
16             if(++i == k){
17                 val = root.val;
18                 return;
19             }
20             inOrder(root.right, k);
21         }
22     }
23 }
leetcode 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.2 MB, 在所有 Java 提交中击败了91.65%的用户

复杂度分析:

时间复杂度:O(n)。最多遍历整棵树,所以时间复杂度为O(n)。
空间复杂度:O(n)。递归栈的深度即是空间复杂度,栈的深度取决于树的高度,当树退化成链表时,最空间复杂度为O(n)。

法二:非递归中序遍历

 1 class Solution {
 2 
 3     public int kthSmallest(TreeNode root, int k) {
 4         // 非递归中序遍历被访问的第k个结点
 5         Stack<TreeNode> stack = new Stack<TreeNode>();
 6         TreeNode cur = root;
 7         int val = 0;
 8         while(!stack.isEmpty() || cur != null){
 9             while(cur != null){
10                 stack.push(cur);
11                 cur = cur.left;
12             }
13             cur = stack.pop();
14             if(--k == 0){
15                 return cur.val;
16             }
17             cur = cur.right;
18         }
19         return val;
20     }
21 }
leetcode 执行用时:1 ms, 在所有 Java 提交中击败了54.12%的用户
内存消耗:38.5 MB, 在所有 Java 提交中击败了71.21%的用户

复杂度分析:

时间复杂度:O(n)。最多遍历整棵树,所以时间复杂度为O(n)。
空间复杂度:O(n)。辅助栈的深度即是空间复杂度,栈的深度取决于树的高度,当树退化成链表时,最空间复杂度为O(n)。

法三:

将所有的结点按中序遍历的顺序存入一个ArrayList, 最后取出 第 k 个元素即可

 1 import java.util.ArrayList;
 2 public class Solution {
 3      // 将所有的结点按中序遍历的顺序存入一个ArrayList, 最后取出 第 k 个元素即可
 4     ArrayList<TreeNode> arr = new ArrayList<>();
 5     TreeNode KthNode(TreeNode pRoot, int k)
 6     {
 7         if(pRoot == null)
 8             return null;
 9         inOrder(pRoot);
10         if(k >= 1 && k <= arr.size())    // 如果 k 在 1 和 最大结点数之间
11             return arr.get(k - 1);
12         return null;        // 说明 k 超过了节点数
13     }
14     
15     void inOrder(TreeNode root){
16         if(root != null){
17             inOrder(root.left);
18             arr.add(root);
19             inOrder(root.right);
20         }
21     }
22 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值