Leetcode
This commit is contained in:
parent
d06e49bcd7
commit
7b8a1436c5
6 changed files with 256 additions and 0 deletions
6
balanced-binary-tree-110/Cargo.toml
Normal file
6
balanced-binary-tree-110/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "balanced-binary-tree-110"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
54
balanced-binary-tree-110/src/main.rs
Normal file
54
balanced-binary-tree-110/src/main.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Definition for a binary tree node.
|
||||||
|
struct Solution {}
|
||||||
|
|
||||||
|
#[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 {
|
||||||
|
pub fn is_balanced(root: Option<Rc<RefCell<TreeNode>>>) -> bool {
|
||||||
|
return check_height(root).is_ok();
|
||||||
|
|
||||||
|
fn check_height(root: Option<Rc<RefCell<TreeNode>>>) -> Result<i32, ()> {
|
||||||
|
if root.is_none() {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let node = root.unwrap();
|
||||||
|
let node_ref = node.borrow();
|
||||||
|
|
||||||
|
// Recursively check left subtree
|
||||||
|
let left_height = check_height(node_ref.left.clone())?;
|
||||||
|
|
||||||
|
// Recursively check right subtree
|
||||||
|
let right_height = check_height(node_ref.right.clone())?;
|
||||||
|
|
||||||
|
// Check if the current node is balanced
|
||||||
|
if (left_height - right_height).abs() > 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the height of the current subtree
|
||||||
|
Ok(1 + left_height.max(right_height))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
||||||
6
minimum-depth-of-binary-tree-111/Cargo.toml
Normal file
6
minimum-depth-of-binary-tree-111/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "minimum-depth-of-binary-tree-111"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
134
minimum-depth-of-binary-tree-111/src/main.rs
Normal file
134
minimum-depth-of-binary-tree-111/src/main.rs
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
struct Solution;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn min_depth(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
|
||||||
|
// Base case: if the root is None, the depth is 0
|
||||||
|
match root {
|
||||||
|
None => 0,
|
||||||
|
Some(node) => {
|
||||||
|
let node = node.borrow();
|
||||||
|
|
||||||
|
// Get the left and right subtree depths
|
||||||
|
let left_depth = Self::min_depth(node.left.clone());
|
||||||
|
let right_depth = Self::min_depth(node.right.clone());
|
||||||
|
|
||||||
|
// Handle cases where one subtree is empty
|
||||||
|
// A leaf node is one with no children, so we need to check both subtrees
|
||||||
|
match (left_depth, right_depth) {
|
||||||
|
(0, 0) => 1, // This is a leaf node (both children are None)
|
||||||
|
(0, _) => 1 + right_depth, // Left subtree is empty, use right
|
||||||
|
(_, 0) => 1 + left_depth, // Right subtree is empty, use left
|
||||||
|
(_, _) => 1 + std::cmp::min(left_depth, right_depth), // Both non-empty, use min
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min_depth_BFS(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
|
||||||
|
// Base case: if the root is None, the depth is 0
|
||||||
|
if root.is_none() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use BFS (level-order traversal) which is more efficient for finding minimum depth
|
||||||
|
// since we can return as soon as we find the first leaf node
|
||||||
|
let mut queue = std::collections::VecDeque::new();
|
||||||
|
queue.push_back((root.unwrap(), 1)); // Start with depth 1 for root
|
||||||
|
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let (node_rc, depth) = queue.pop_front().unwrap();
|
||||||
|
let node = node_rc.borrow();
|
||||||
|
|
||||||
|
// If we found a leaf node, return its depth immediately
|
||||||
|
if node.left.is_none() && node.right.is_none() {
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add children to the queue
|
||||||
|
if let Some(left) = &node.left {
|
||||||
|
queue.push_back((left.clone(), depth + 1));
|
||||||
|
}
|
||||||
|
if let Some(right) = &node.right {
|
||||||
|
queue.push_back((right.clone(), depth + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should never be reached if the tree is valid
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Example 1: A balanced tree with depth 2
|
||||||
|
// 3
|
||||||
|
// / \
|
||||||
|
// 9 20
|
||||||
|
let mut root1 = TreeNode::new(3);
|
||||||
|
root1.left = Some(Rc::new(RefCell::new(TreeNode::new(9))));
|
||||||
|
root1.right = Some(Rc::new(RefCell::new(TreeNode::new(20))));
|
||||||
|
let tree1 = Some(Rc::new(RefCell::new(root1)));
|
||||||
|
|
||||||
|
// Example 2: A tree with one branch longer than the other
|
||||||
|
// 1
|
||||||
|
// \
|
||||||
|
// 2
|
||||||
|
// \
|
||||||
|
// 3
|
||||||
|
let mut root2 = TreeNode::new(1);
|
||||||
|
let mut node2 = TreeNode::new(2);
|
||||||
|
node2.right = Some(Rc::new(RefCell::new(TreeNode::new(3))));
|
||||||
|
root2.right = Some(Rc::new(RefCell::new(node2)));
|
||||||
|
let tree2 = Some(Rc::new(RefCell::new(root2)));
|
||||||
|
|
||||||
|
// Example 3: A tree with minimum depth different from maximum depth
|
||||||
|
// 1
|
||||||
|
// / \
|
||||||
|
// 2 3
|
||||||
|
// / \
|
||||||
|
// 4 5
|
||||||
|
// /
|
||||||
|
// 6
|
||||||
|
let mut root3 = TreeNode::new(1);
|
||||||
|
let mut node2 = TreeNode::new(2);
|
||||||
|
let mut node3 = TreeNode::new(3);
|
||||||
|
let mut node4 = TreeNode::new(4);
|
||||||
|
node4.left = Some(Rc::new(RefCell::new(TreeNode::new(6))));
|
||||||
|
node2.left = Some(Rc::new(RefCell::new(node4)));
|
||||||
|
node3.right = Some(Rc::new(RefCell::new(TreeNode::new(5))));
|
||||||
|
root3.left = Some(Rc::new(RefCell::new(node2)));
|
||||||
|
root3.right = Some(Rc::new(RefCell::new(node3)));
|
||||||
|
let tree3 = Some(Rc::new(RefCell::new(root3)));
|
||||||
|
|
||||||
|
// Example 4: Empty tree
|
||||||
|
let tree4: Option<Rc<RefCell<TreeNode>>> = None;
|
||||||
|
|
||||||
|
// Example 5: Tree with only one node
|
||||||
|
let tree5 = Some(Rc::new(RefCell::new(TreeNode::new(1))));
|
||||||
|
|
||||||
|
// Print the minimum depth of each tree
|
||||||
|
println!("Min depth of tree1: {}", min_depth_BFS(tree1));
|
||||||
|
println!("Min depth of tree2: {}", Solution::min_depth(tree2));
|
||||||
|
println!("Min depth of tree3: {}", Solution::min_depth(tree3));
|
||||||
|
println!("Min depth of tree4: {}", Solution::min_depth(tree4));
|
||||||
|
println!("Min depth of tree5: {}", Solution::min_depth(tree5));
|
||||||
|
}
|
||||||
6
path-sum-112/Cargo.toml
Normal file
6
path-sum-112/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "path-sum-112"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
50
path-sum-112/src/main.rs
Normal file
50
path-sum-112/src/main.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
// 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Solution;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
impl Solution {
|
||||||
|
pub fn has_path_sum(root: Option<Rc<RefCell<TreeNode>>>, target_sum: i32) -> bool {
|
||||||
|
// Base case: If the tree is empty, there's no path
|
||||||
|
if root.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let node = root.unwrap();
|
||||||
|
let node_ref = node.borrow();
|
||||||
|
let current_val = node_ref.val;
|
||||||
|
|
||||||
|
// If this is a leaf node, check if the value equals the remaining target sum
|
||||||
|
if node_ref.left.is_none() && node_ref.right.is_none() {
|
||||||
|
return current_val == target_sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, check if either subtree has a path with the remaining sum
|
||||||
|
let remaining_sum = target_sum - current_val;
|
||||||
|
|
||||||
|
Solution::has_path_sum(node_ref.left.clone(), remaining_sum)
|
||||||
|
|| Solution::has_path_sum(node_ref.right.clone(), remaining_sum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue