new prolem solved

main
Luca Lombardo 10 months ago
parent bffa5b871f
commit 3108b2e612

@ -0,0 +1,21 @@
**Objective**: Given a binary tree, find the maximum path sum from one leaf node to another.
## Idea
The problem statement suggests that we're dealing with a tree traversal problem where we need to calculate the maximum path sum. The algorithm we're using is a variant of Depth-First Search (DFS).
Here's the general idea:
1. **Depth-First Search (DFS)**: We're using a DFS approach to traverse the tree. DFS visits a node's child nodes before visiting its sibling nodes, diving deep into the tree structure before backtracking. This is ideal for our problem because we need to explore all the way from root to leaf nodes to calculate path sums.
2. **Post-order Traversal**: More specifically, we're using a post-order traversal (left child, right child, root). This allows us to calculate the maximum path sum for the left and right subtrees of each node before calculating the maximum path sum that includes the node itself.
3. **Maintaining a Global Maximum**: As we calculate the maximum path sum for each node, we compare it with a global maximum value. If it's larger, we update the global maximum. This ensures that we always have the maximum path sum found so far.
4. **Returning Maximum Branch Sum**: For each node, we return the maximum path sum that includes the node and either its left child or its right child (whichever is larger). This is because a path can't include both the left and right children of a node, as it wouldn't be a valid path (it would form a loop).
So, we're visiting the tree in a depth-first manner, exploring all paths from the root to the leaf nodes, and keeping track of the maximum path sum found so far.
## Complexity Analysis
The time complexity for this algorithm is $O(N)$, where N is the number of nodes in the tree. This is because we visit each node once. The space complexity is $O$(height of the tree), which is the maximum depth of the call stack during the DFS traversal.

@ -1,3 +1,41 @@
fn main() {
println!("Hello, world!");
use std::cmp;
struct Node {
data: i32,
left: Option<Box<Node>>,
right: Option<Box<Node>>,
}
impl Node {
fn new(val: i32) -> Node {
Node {
data: val,
left: None,
right: None,
}
}
}
fn max_path_sum_util(root: &Option<Box<Node>>, res: &mut i32) -> i32 {
match root {
Some(node) => {
let ls = max_path_sum_util(&node.left, res); // computes the max path sum in the left subtree
let rs = max_path_sum_util(&node.right, res); // computes the max path sum in the right subtree
match (&node.left, &node.right) {
(Some(_), Some(_)) => { // if both left and right subtrees are present
*res = cmp::max(*res, ls + rs + node.data); // update the result if needed as the max path sum can be in the left subtree, right subtree or the path can go through the root
cmp::max(ls, rs) + node.data // return the max path sum from the left or right subtree
}
(None, _) => rs + node.data, // if left subtree is not present, return the max path sum from the right subtree
(_, None) => ls + node.data, // if right subtree is not present, return the max path sum from the left subtree
}
}
None => 0, // if the root is None, return 0
}
}
fn max_path_sum(root: &Option<Box<Node>>) -> i32 { // function to compute the max path sum
let mut res = std::i32::MIN; // initialize the result with the minimum value of i32
max_path_sum_util(root, &mut res); // call the utility function to compute the max path sum
res // return the result
}

@ -0,0 +1,8 @@
[package]
name = "is-bipartite"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

@ -0,0 +1,4 @@
# Idea
A graph is bipartite means that it can be divided into two sets of nodes, such that all edges connect a node from one set to a node from the other set. Let's call this set A and B. The simplest way to understand the idea is to say that this node in this graph cannot be in the same set as his neighbor.
We can create the two sets as EVEN and ODD. We start from a node and we put it in the EVEN set. Then we put all his neighbors in the ODD set. Then we put all their neighbors in the EVEN set, and so on. If we find a node that is already in a set, and we try to put it in the other set, then we have a conflict and the graph is not bipartite.

@ -0,0 +1,39 @@
use std::collections::VecDeque;
struct Solution;
impl Solution {
fn dfs(graph: &Vec<Vec<i32>>, odd: &mut Vec<i32>, i: usize) -> bool {
if odd[i] != 0 {
return true;
}
let mut q = VecDeque::new();
odd[i] = -1; // this marks the node as visited
while q.len() > 0 {
let i = q.pop_front().unwrap();
// go through all the neighbors
for &nei in &graph[i] {
if odd[i] == odd[nei as usize] {
return false;
}
else if odd[nei as usize] == 0 {
q.push_back(nei as usize);
odd[nei as usize] = -odd[i];
}
}
}
return true;
}
pub fn is_bipartite(graph: Vec<Vec<i32>>) -> bool {
let mut odd = vec![0; graph.len()]; // map node i to odd=1, even=-1
for i in 0..graph.len() {
if !Self::dfs(&graph, &mut odd, i) {
return false;
}
}
return true;
}
}
Loading…
Cancel
Save