File tree Expand file tree Collapse file tree 5 files changed +131
-0
lines changed
binary-tree-maximum-path-sum
maximum-depth-of-binary-tree Expand file tree Collapse file tree 5 files changed +131
-0
lines changed Original file line number Diff line number Diff line change 1+ # Time Complexity: O(N) - visit each node once.
2+ # Space Complexity: O(H) - recursive call stack, where H is the tree height.
3+ # - O(log N) for balanced trees, O(N) for skewed trees.
4+
5+ class Solution :
6+ def maxPathSum (self , root : Optional [TreeNode ]) -> int :
7+ def dfs (node ):
8+ nonlocal ans
9+ if not node :
10+ return 0
11+
12+ # get the max path sum from left and right subtrees (ignore negatives)
13+ left = max (dfs (node .left ), 0 )
14+ right = max (dfs (node .right ), 0 )
15+
16+ # update the global max path sum including this node
17+ ans = max (ans , left + right + node .val )
18+
19+ # return the max path sum that can be extended to the parent
20+ return max (left , right ) + node .val
21+
22+ # initialize with the smallest possible value
23+ ans = float ('-inf' )
24+ # start DFS from the root
25+ dfs (root )
26+ return ans
Original file line number Diff line number Diff line change 1+ # Time Complexity: O(N) - iterate through all edges and nodes at most once.
2+ # Space Complexity: O(N) - store the graph as an adjacency list and track visited nodes.
3+
4+ class Solution :
5+ def valid_tree (self , n : int , edges : List [List [int ]]) -> bool :
6+ # a tree with 'n' nodes must have exactly 'n-1' edges
7+ if len (edges ) != n - 1 :
8+ return False
9+
10+ # build an adjacency list (graph representation)
11+ graph = {i : [] for i in range (n )}
12+ for u , v in edges :
13+ graph [u ].append (v )
14+ graph [v ].append (u )
15+
16+ # use BFS to check if the graph is fully connected and acyclic
17+ visited = set ()
18+ queue = [0 ]
19+ visited .add (0 )
20+
21+ while queue :
22+ node = queue .pop (0 )
23+ for neighbor in graph [node ]:
24+ if neighbor in visited :
25+ continue
26+ visited .add (neighbor )
27+ queue .append (neighbor )
28+
29+ # if we visited all nodes, it's a valid tree
30+ return len (visited ) == n
Original file line number Diff line number Diff line change 1+ # Time Complexity: O(N) - visit each node once.
2+ # Space Complexity: O(H) - the recursion stack goes as deep as the height of the tree.
3+ # - Worst case (skewed tree): O(N)
4+ # - Best case (balanced tree): O(log N)
5+
6+ class Solution :
7+ def maxDepth (self , root : Optional [TreeNode ]) -> int :
8+ # if there's no node, the depth is just 0.
9+ if not root :
10+ return 0
11+
12+ # recursively get the depth of left and right subtrees
13+ # then add 1 for the current node
14+ return 1 + max (self .maxDepth (root .left ), self .maxDepth (root .right ))
Original file line number Diff line number Diff line change 1+ # Time Complexity: O(N log N) - sorting takes O(N log N), and merging takes O(N)
2+ # Space Complexity: O(N) - store the merged intervals in a new list.
3+
4+ class Solution :
5+
6+ def merge (self , intervals : List [List [int ]]) -> List [List [int ]]:
7+ # sort the intervals by their start values
8+ intervals .sort (key = lambda x : x [0 ])
9+
10+ # this will store our final merged intervals
11+ merged = []
12+ # start with the first interval
13+ prev = intervals [0 ]
14+
15+ # iterate through the sorted intervals
16+ for interval in intervals [1 :]:
17+ if interval [0 ] <= prev [1 ]:
18+ # overlapping intervals → merge them by updating 'end' value
19+ prev [1 ] = max (prev [1 ], interval [1 ])
20+ else :
21+ # no overlap → add 'prev' to the merged list and update 'prev'
22+ merged .append (prev )
23+ prev = interval
24+
25+ merged .append (prev )
26+
27+ return merged
Original file line number Diff line number Diff line change 1+ # Time Complexity: O(N) - traverse the list three times:
2+ # (1) find the middle (O(N)),
3+ # (2) reverse the second half (O(N)),
4+ # (3) merge the two halves (O(N)).
5+ # Space Complexity: O(1) - use a few extra pointers, no additional data structures.
6+
7+ class Solution :
8+ def reorderList (self , head : Optional [ListNode ]) -> None :
9+ # find the middle of the list using slow & fast pointers
10+ slow , fast = head , head .next
11+ while fast and fast .next :
12+ slow = slow .next
13+ fast = fast .next .next
14+
15+ # reverse the second half of the list
16+ second = slow .next
17+ # cut the list into two halves
18+ slow .next = None
19+ prev = None
20+
21+ while second :
22+ temp = second .next
23+ second .next = prev
24+ prev = second
25+ second = temp
26+
27+ # merge the two halves (alternating nodes)
28+ first , second = head , prev
29+
30+ while second :
31+ temp1 , temp2 = first .next , second .next
32+ first .next = second
33+ second .next = temp1
34+ first , second = temp1 , temp2
You can’t perform that action at this time.
0 commit comments