File tree 5 files changed +131
-0
lines changed
binary-tree-maximum-path-sum
maximum-depth-of-binary-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