54. 二叉搜索树的第 k 大节点

devtools/2024/10/15 14:01:23/

comments: true
difficulty: 简单
edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9854.%20%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E7%AC%ACk%E5%A4%A7%E8%8A%82%E7%82%B9/README.md

面试题 54. 二叉搜索树的第 k 大节点

题目描述

给定一棵二叉搜索树,请找出其中第 k 大的节点的值。

 

示例 1:

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

示例 2:

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

 

限制:

  • 1 ≤ k ≤ 二叉搜索树元素个数

解法

方法一:反序中序遍历

由于二叉搜索树的中序遍历是升序的,因此可以反序中序遍历,即先递归遍历右子树,再访问根节点,最后递归遍历左子树。

这样就可以得到一个降序的序列,第 k k k 个节点就是第 k k k 大的节点。

时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)。其中 n n n 是二叉搜索树的节点个数。

Python3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def kthLargest(self, root: TreeNode, k: int) -> int:def dfs(root):nonlocal k, ansif root is None or k == 0:returndfs(root.right)k -= 1if k == 0:ans = root.valdfs(root.left)ans = 0dfs(root)return ans
Java
/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {private int k;private int ans;public int kthLargest(TreeNode root, int k) {this.k = k;dfs(root);return ans;}private void dfs(TreeNode root) {if (root == null || k == 0) {return;}dfs(root.right);if (--k == 0) {ans = root.val;}dfs(root.left);}
}
C++
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:int kthLargest(TreeNode* root, int k) {int ans = 0;function<void(TreeNode*)> dfs = [&](TreeNode* root) {if (!root || !k) {return;}dfs(root->right);if (--k == 0) {ans = root->val;}dfs(root->left);};dfs(root);return ans;}
};
Go
/*** Definition for a binary tree node.* type TreeNode struct {*     Val int*     Left *TreeNode*     Right *TreeNode* }*/
func kthLargest(root *TreeNode, k int) (ans int) {var dfs func(*TreeNode)dfs = func(root *TreeNode) {if root == nil || k == 0 {return}dfs(root.Right)k--if k == 0 {ans = root.Val}dfs(root.Left)}dfs(root)return
}
TypeScript
/*** Definition for a binary tree node.* class TreeNode {*     val: number*     left: TreeNode | null*     right: TreeNode | null*     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {*         this.val = (val===undefined ? 0 : val)*         this.left = (left===undefined ? null : left)*         this.right = (right===undefined ? null : right)*     }* }*/function kthLargest(root: TreeNode | null, k: number): number {let res = 0;const dfs = (root: TreeNode | null) => {if (root == null) {return;}dfs(root.right);if (--k === 0) {res = root.val;return;}dfs(root.left);};dfs(root);return res;
}
Rust
// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
//   pub val: i32,
//   pub left: Option<Rc<RefCell<TreeNode>>>,
//   pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
//   #[inline]
//   pub fn new(val: i32) -> Self {
//     TreeNode {
//       val,
//       left: None,
//       right: None
//     }
//   }
// }
use std::cell::RefCell;
use std::rc::Rc;impl Solution {fn dfs(root: &Option<Rc<RefCell<TreeNode>>>, arr: &mut Vec<i32>) {if let Some(node) = root {let node = node.borrow();Solution::dfs(&node.right, arr);arr.push(node.val);Solution::dfs(&node.left, arr)}}pub fn kth_largest(root: Option<Rc<RefCell<TreeNode>>>, k: i32) -> i32 {let mut arr = vec![];Solution::dfs(&root, &mut arr);arr[(k - 1) as usize]}
}
JavaScript
/*** Definition for a binary tree node.* function TreeNode(val) {*     this.val = val;*     this.left = this.right = null;* }*/
/*** @param {TreeNode} root* @param {number} k* @return {number}*/
var kthLargest = function (root, k) {let ans = 0;const dfs = root => {if (!root || !k) {return;}dfs(root.right);if (--k == 0) {ans = root.val;}dfs(root.left);};dfs(root);return ans;
};
C#
/*** Definition for a binary tree node.* public class TreeNode {*     public int val;*     public TreeNode left;*     public TreeNode right;*     public TreeNode(int x) { val = x; }* }*/
public class Solution {private int ans;private int k;public int KthLargest(TreeNode root, int k) {this.k = k;dfs(root);return ans;}private void dfs(TreeNode root) {if (root == null || k == 0) {return;}dfs(root.right);if (--k == 0) {ans = root.val;}dfs(root.left);}
}
Swift
/* public class TreeNode {
*     public var val: Int
*     public var left: TreeNode?
*     public var right: TreeNode?
*     public init(_ val: Int) {
*         self.val = val
*         self.left = nil
*         self.right = nil
*     }
* }
*/class Solution {private var k: Int = 0private var ans: Int = 0func kthLargest(_ root: TreeNode?, _ k: Int) -> Int {self.k = kdfs(root)return ans}private func dfs(_ root: TreeNode?) {guard let root = root, k > 0 else { return }dfs(root.right)k -= 1if k == 0 {ans = root.valreturn}dfs(root.left)}
}

http://www.ppmy.cn/devtools/112757.html

相关文章

【加密算法基础——对称加密和非对称加密】

对称加密与非对称加密 对称加密和非对称加密是两种基本的加密方法&#xff0c;各自有不同的特点和用途。以下是详细比较&#xff1a; 1. 对称加密 特点 密钥: 使用相同的密钥进行加密和解密。发送方和接收方必须共享这个密钥。速度: 通常速度较快&#xff0c;适合处理大量数…

华南医电科技集团受邀出席中马建交50周年高级别经贸合作交流活动

左:马来西亚第九任首拿督斯里 伊斯迈尔沙必里雅各布; 右:华南医电董事长陈广元 在庆祝中国和马来西亚建交50周年的辉煌时刻,中马两国间的经贸合作不仅承载着历史的重任,更展望着未来无限的广阔前景。2024年,作为这一重要里程碑的纪念之年,中马两国政府及商界精英携手举办了一…

Redis 在 Spring Boot 项目中的实际应用及问题解决

引言 Redis 是一款开源的内存数据库&#xff0c;因其卓越的性能、丰富的数据类型以及强大的功能&#xff0c;广泛应用于各种应用场景中&#xff0c;尤其在分布式系统中扮演着缓存、消息队列和分布式锁等重要角色。在 Spring Boot 项目中&#xff0c;Redis 作为缓存层和锁机制&…

堆排序,快速排序

目录 1.堆排序 2.快速排序 1.hoare版本 2.挖坑法 3.前后指针法 注意点 1.堆排序 void Swap(int* a, int* b) {int tmp *a;*a *b;*b tmp; } void adjustdown(int* a, int n, int parent) {int child parent * 2 1;while (child < n){if (child 1 < n &&am…

SpringSecurity原理解析(七):权限校验流程

SpringSecurity是一个权限管理框架&#xff0c;核心功能就是认证和授权&#xff1b;前边已经介绍了认证流程&#xff0c; 这里看下授权的流程和核心类。 一、权限管理的实现 1、开启对权限管理的注解控制 工程中后端各种请求资源要想被SpringSecurity的权限管理控制&#xf…

django orm增删改查操作

1. 基本操作 1.1 创建对象 可以通过 Django ORM 来创建数据库中的记录。 示例&#xff1a; # 方法1&#xff1a;先创建对象&#xff0c;再保存 person Person(nameAlice, age30, emailaliceexample.com) person.save()# 方法2&#xff1a;直接创建 person Person.objects…

标准库标头 <bit>(C++20)学习

<bit>头文件是数值库的一部分。定义用于访问、操作和处理各个位和位序列的函数。例如&#xff0c;有函数可以旋转位、查找连续集或已清除位的数量、查看某个数是否为 2 的整数幂、查找表示数字的最小位数等。 类型 endian (C20) 指示标量类型的端序 (枚举) 函数 bit_ca…

实现互联网发送预警服务邮件

linux安装mailx实现互联网邮件 一、本机发送邮件二、邮箱发送报警邮件2.1.开启smtp服务,QQ申请SMTP功能,开通授权码2.2.修改配置文件2.3.发送邮件 endl 一、本机发送邮件 yum -y install postfix mailx systemctl enable --now postfixyum -y install mailx二、邮箱发送报警邮…