[路飞]_算法_ 二叉搜索树中第K小的元素——递归,优先队列

141 阅读1分钟

题目描述

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

 

示例 1:

image.png 输入:root = [3,1,4,null,2], k = 1 输出:1 示例 2:

image.png 输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3  

 

提示:

  • 树中的节点数为 n 。
  • 1 <= k <= n <= 104
  • 0 <= Node.val <= 104  

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/kt… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

此处撰写解题思路 image.png
遍历节点,创建一个队列保存最小的k个元素
通过二叉搜索树特性知,右子节点始终大于根节点,所以,当已经收集到k个最小元素之后,就可以不遍历右子树了,优化时间复杂度

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} k
 * @return {number}
 */
var kthSmallest = function(root, k) {
    //遍历节点
    var help = function(root) {
      if(!root) return;//空节点
      help(root.left);//继续遍历左节点
      if(kList.length<k){//队列满了可以不遍历右子树了
          help(root.right);
      }
      add(root);
   };
   //把值添加到队列中
   var add= function(root) {
     //每次都找到比当前大的元素插入它前面,没找到就push到最后,就能始终维护一个升序排列的队列
       for(let i=0;i<kList.length;i++){
           if(kList[i]>root.val){
               kList.splice(i,0,root.val);
               return
           }

       }
       if(kList.length<k){
          kList.push(root.val)
       }
      
   };

    let kList=[];
    help(root);
    return kList[k-1]

};