「前端刷题」230.二叉搜索树中第K小的元素(MEDIUM)

216 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

题目(Kth Smallest Element in a BST)

链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst
解决数:1573
通过率:75.7%
标签:树 深度优先搜索 二叉搜索树 二叉树 
相关公司:amazon facebook google 

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

 

示例 1:

输入: root = [3,1,4,null,2], k = 1
输出: 1

示例 2:

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

 

 

提示:

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

 

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

思路

迭代

let kthSmallest = function(root, k) {
    let stack = []
    let node = root
    
    while(node || stack.length) {
        // 遍历左子树
        while(node) {
            stack.push(node)
            node = node.left
        }
      
        node = stack.pop()
        if(--k === 0) {
            return node.val
        }
        node = node.right
    }
    return null
}

递归

let kthSmallest = function(root, k) {
    let res = null
    let inOrderTraverseNode = function(node) {
        if(node !== null && k > 0) {
            // 先遍历左子树
            inOrderTraverseNode(node.left)
            // 然后根节点
            if(--k === 0) {
                res = node.val
                return 
            }
            // 再遍历右子树
            inOrderTraverseNode(node.right)
        }
    }
    inOrderTraverseNode(root)
    return res
}

or

中间节点先输出,在中间每次减一,减到k为1,即为第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) {
    let max = -1;

    function dfs(node) {
        if(!node) return;

        max === -1 && dfs(node.left);      
        if(k === 1 && max === -1) {
            max = node.val;
        }
        k--;
        max === -1 && dfs(node.right);
    }
    dfs(root);

     return max;
};

二叉搜索树 又称 二叉排序树,每个节点左子树的所有节点必定小于这个节点。因此想要获取倒数第k小的,只需要中序遍历即可。

var kthSmallest = function(root, k) {
	function* inOrderTraverse(t) {
		if(t){
			yield* inOrderTraverse(t.left)
			yield  t.val
			yield* inOrderTraverse(t.right)
		}
	}
	let result = []
	for(let node of inOrderTraverse(root)){
		result.push(node)
	}
	return result[k - 1]
};