This commit is contained in:
Håkon Størdal 2025-05-02 19:22:31 +02:00
parent d06e49bcd7
commit 7b8a1436c5
6 changed files with 256 additions and 0 deletions

View file

@ -0,0 +1,6 @@
[package]
name = "balanced-binary-tree-110"
version = "0.1.0"
edition = "2024"
[dependencies]

View 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!");
}

View file

@ -0,0 +1,6 @@
[package]
name = "minimum-depth-of-binary-tree-111"
version = "0.1.0"
edition = "2024"
[dependencies]

View 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
View 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
View 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!");
}