Leetcode——230. 二叉搜索树中第K小的元素

230. 二叉搜索树中第K小的元素

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第
k 个最小的元素。

题目**

说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
示例 1:
输入: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
输出: 1

示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / \
     3   6
    / \
   2   4
  /
 1
输出: 3

进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?

二叉树数据结构(题目给出)**

 Definition for a binary tree node.
 
 public class TreeNode {
     int val;
     TreeNode left;
     TreeNode right;
     TreeNode() {}
     TreeNode(int val) { this.val = val; }
     TreeNode(int val, TreeNode left, TreeNode right) {
         this.val = val;
         this.left = left;
         this.right = right;
     }
 }

1、递归**

思想**

计算左子树结点个数numL
如果numL+1等于k,说明根结点第k小元素,直接返回
如果numL大于等于K,第k小元素在左子树,递归查找
否则,第k小元素在右子树,递归查找

代码**

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        int numL = countNode(root.left);//计算左子树结点数
        if(numL + 1== k){//如果根结点数值第k小,直接返回
            return root.val;
        }
        //递归
        else if(k <= numL){//如果第k小元素在左子树中
            return kthSmallest(root.left, k);
        }
        else{//否则在右子树中
            return kthSmallest(root.right, k - numL - 1);
        }
    }
    public int countNode(TreeNode root) {
        if(root == null){
            return 0;
        }
        return countNode(root.left) + countNode(root.right) + 1;
    }
}

2、中序数组法**

思想**

利用二叉搜索树的中序序列有序将其转换为有序数组,然后直接返回下标k-1处元素即可

代码**

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        ArrayList<Integer> arr = new ArrayList<Integer> ();
        inOrder(root, arr);
        return arr.get(k-1);//注意不可以用arr[k-1]
    //    return arr.get(k-1);//E	get(int index),Returns the element at the specified position in this list.
    }
    public ArrayList inOrder(TreeNode root, ArrayList<Integer> arr) {//将二叉搜索树进行中序遍历转换成有序数组
        if(root == null){
            return arr;
        }
        inOrder(root.left, arr);
        arr.add(root.val);
        inOrder(root.right, arr);
        return arr;
    }
}

3、中序栈法**

思想**

利用二叉搜索树的中序序列有序,先将所有的左孩子入栈,遍历到最小值,之后依次弹出最小值,如果有右孩子也要遍历,直到找到第k个弹出元素即可

代码**

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();//用法没搞懂
    //    Stack<TreeNode> stack = new Stack<TreeNode> ();
        while(true){
            while(root != null){
                stack.add(root);
                root = root.left;
            }
            root = stack.removeLast();
            k--;
            if(k == 0){
                return root.val;
            }
            root = root.right;
        }
    }
}

问题

LinkedList stack = new LinkedList();//用法没搞懂
stack.add(root);
root = stack.removeLast();

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李霁明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值