Skip to content

Commit 1e8228d

Browse files
committed
LC 2583. Kth Largest Sum in a Binary Tree (Rust)
1 parent 278235f commit 1e8228d

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ to the solution in this repository.
721721
| [2540. Minimum Common Value][lc2540] | 🟢 Easy | [![rust](res/rs.png)][lc2540rs] |
722722
| [2542. Maximum Subsequence Score][lc2542] | 🟠 Medium | [![rust](res/rs.png)][lc2542rs] |
723723
| [2543. Check if Point Is Reachable][lc2543] | 🔴 Hard | [![python](res/py.png)][lc2543py] [![rust](res/rs.png)][lc2543rs] |
724+
| [2583. Kth Largest Sum in a Binary Tree][lc2583] | 🟠 Medium | [![rust](res/rs.png)][lc2583rs] |
724725
| [2585. Number of Ways to Earn Points][lc2585] | 🔴 Hard | [![python](res/py.png)][lc2585py] [![rust](res/rs.png)][lc2585rs] |
725726
| [2616. Minimize the Maximum Difference of Pairs][lc2616] | 🟠 Medium | [![rust](res/rs.png)][lc2616rs] |
726727
| [2618. Check if Object Instance of Class][lc2618] | 🟠 Medium | [![js](res/js.png)][lc2618js] |
@@ -2364,6 +2365,8 @@ to the solution in this repository.
23642365
[lc2543]: https://leetcode.com/problems/check-if-point-is-reachable/
23652366
[lc2543py]: leetcode/check-if-point-is-reachable.py
23662367
[lc2543rs]: leetcode/check-if-point-is-reachable.rs
2368+
[lc2583]: https://leetcode.com/problems/kth-largest-sum-in-a-binary-tree/
2369+
[lc2583rs]: leetcode/kth-largest-sum-in-a-binary-tree.rs
23672370
[lc2585]: https://leetcode.com/problems/number-of-ways-to-earn-points/
23682371
[lc2585py]: leetcode/number-of-ways-to-earn-points.py
23692372
[lc2585rs]: leetcode/number-of-ways-to-earn-points.rs
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// 2583. Kth Largest Sum in a Binary Tree
2+
// 🟠 Medium
3+
//
4+
// https://leetcode.com/problems/kth-largest-sum-in-a-binary-tree/
5+
//
6+
// Tags: Tree - Breadth-First Search - Sorting - Binary Tree
7+
8+
use std::cell::RefCell;
9+
use std::collections::{BinaryHeap, VecDeque};
10+
use std::rc::Rc;
11+
12+
// Definition for a binary tree node.
13+
#[derive(Debug, PartialEq, Eq)]
14+
pub struct TreeNode {
15+
pub val: i32,
16+
pub left: Option<Rc<RefCell<TreeNode>>>,
17+
pub right: Option<Rc<RefCell<TreeNode>>>,
18+
}
19+
20+
impl TreeNode {
21+
#[inline]
22+
pub fn new(val: i32) -> Self {
23+
TreeNode {
24+
val,
25+
left: None,
26+
right: None,
27+
}
28+
}
29+
}
30+
31+
struct Solution;
32+
impl Solution {
33+
/// Use BFS to process the tree by level, for each level, compute the sum of it's node
34+
/// values and store that, then return the kth sum, I use a heap for that, but we could
35+
/// also use other methods, for example a vector then sort it.
36+
///
37+
/// Time complexity: O(nlog(n)) - We visit each node in the tree in linear time, but we
38+
/// push/pop them from the heap of size n.
39+
/// Space complexity: O(n) - The size of the heap. We push one i64 for each level, if the
40+
/// tree is skeewed, it could have as many levels as nodes.
41+
///
42+
/// Runtime 8 ms Beats 100%
43+
/// Memory 11.84 MB Beats 33%
44+
pub fn kth_largest_level_sum(root: Option<Rc<RefCell<TreeNode>>>, k: i32) -> i64 {
45+
let n = k as usize + 1;
46+
let mut heap = BinaryHeap::with_capacity(n);
47+
let mut queue = VecDeque::from([root.unwrap()]);
48+
let mut level_sum: i64;
49+
while !queue.is_empty() {
50+
level_sum = 0;
51+
for _ in 0..queue.len() {
52+
if let Some(rc) = queue.pop_front() {
53+
let node = rc.borrow();
54+
level_sum += node.val as i64;
55+
if let Some(left) = node.left.clone() {
56+
queue.push_back(left);
57+
}
58+
if let Some(right) = node.right.clone() {
59+
queue.push_back(right);
60+
}
61+
}
62+
}
63+
heap.push(level_sum);
64+
}
65+
for _ in 0..k - 1 {
66+
heap.pop();
67+
}
68+
*heap.peek().unwrap()
69+
}
70+
}
71+
72+
// Tests.
73+
fn main() {
74+
let tree1 = Some(Rc::new(RefCell::new(TreeNode {
75+
val: 5,
76+
left: Some(Rc::new(RefCell::new(TreeNode {
77+
val: 8,
78+
left: Some(Rc::new(RefCell::new(TreeNode {
79+
val: 2,
80+
left: Some(Rc::new(RefCell::new(TreeNode {
81+
val: 4,
82+
left: None,
83+
right: None,
84+
}))),
85+
right: Some(Rc::new(RefCell::new(TreeNode {
86+
val: 6,
87+
left: None,
88+
right: None,
89+
}))),
90+
}))),
91+
right: Some(Rc::new(RefCell::new(TreeNode {
92+
val: 1,
93+
left: None,
94+
right: None,
95+
}))),
96+
}))),
97+
right: Some(Rc::new(RefCell::new(TreeNode {
98+
val: 9,
99+
left: Some(Rc::new(RefCell::new(TreeNode {
100+
val: 3,
101+
left: None,
102+
right: None,
103+
}))),
104+
right: Some(Rc::new(RefCell::new(TreeNode {
105+
val: 7,
106+
left: None,
107+
right: None,
108+
}))),
109+
}))),
110+
})));
111+
let tree2 = Some(Rc::new(RefCell::new(TreeNode {
112+
val: 1,
113+
left: Some(Rc::new(RefCell::new(TreeNode {
114+
val: 2,
115+
left: Some(Rc::new(RefCell::new(TreeNode {
116+
val: 3,
117+
left: None,
118+
right: None,
119+
}))),
120+
right: None,
121+
}))),
122+
right: None,
123+
})));
124+
let tests = [(tree1, 2, 13), (tree2, 1, 3)];
125+
println!("\n\x1b[92m» Running {} tests...\x1b[0m", tests.len());
126+
let mut success = 0;
127+
for (i, t) in tests.iter().enumerate() {
128+
let res = Solution::kth_largest_level_sum(t.0.clone(), t.1);
129+
if res == t.2 {
130+
success += 1;
131+
println!("\x1b[92m✔\x1b[95m Test {} passed!\x1b[0m", i);
132+
} else {
133+
println!(
134+
"\x1b[31mx\x1b[95m Test {} failed expected: {:?} but got {}!!\x1b[0m",
135+
i, t.1, res
136+
);
137+
}
138+
}
139+
println!();
140+
if success == tests.len() {
141+
println!("\x1b[30;42m✔ All tests passed!\x1b[0m")
142+
} else if success == 0 {
143+
println!("\x1b[31mx \x1b[41;37mAll tests failed!\x1b[0m")
144+
} else {
145+
println!(
146+
"\x1b[31mx\x1b[95m {} tests failed!\x1b[0m",
147+
tests.len() - success
148+
)
149+
}
150+
}

0 commit comments

Comments
 (0)