Skip to content

Commit 00fbc77

Browse files
committed
add more solutions
1 parent db8ea90 commit 00fbc77

35 files changed

+2634
-0
lines changed

python/add_two_numbers.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# [2. Add Two Numbers](https://leetcode.com/problems/add-two-numbers/)
2+
3+
## Approach: Iterative Solution with Carry
4+
5+
### Solution
6+
python
7+
```python
8+
# Time Complexity: O(max(m, n)), where m and n are the lengths of the two lists
9+
# Space Complexity: O(max(m, n)), for the new linked list
10+
11+
class ListNode:
12+
def __init__(self, val=0, next=None):
13+
self.val = val
14+
self.next = next
15+
16+
class Solution:
17+
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
18+
dummy = ListNode(0) # Dummy node to simplify the process
19+
current = dummy # Pointer to the current node in the result list
20+
carry = 0 # Store carry from the addition
21+
22+
# Traverse both lists
23+
while l1 is not None or l2 is not None or carry != 0:
24+
sum = carry # Start with the carry
25+
26+
# Add values from l1 and l2 if they exist
27+
if l1 is not None:
28+
sum += l1.val
29+
l1 = l1.next
30+
if l2 is not None:
31+
sum += l2.val
32+
l2 = l2.next
33+
34+
# Calculate new carry and the digit to store
35+
carry = sum // 10
36+
current.next = ListNode(sum % 10) # Store the last digit of the sum
37+
current = current.next # Move to the next node
38+
39+
return dummy.next # Skip the dummy node
40+
```
41+

python/basic_calculator_2.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/)
2+
3+
## Approach: Using a Stack for Intermediate Results
4+
5+
### Solution
6+
python
7+
```python
8+
# Time Complexity: O(n)
9+
# Space Complexity: O(n)
10+
11+
class Solution:
12+
def calculate(self, s: str) -> int:
13+
stack = []
14+
current_number = 0
15+
operation = '+' # Default operation is addition
16+
17+
for i in range(len(s)):
18+
c = s[i]
19+
20+
# Build the current number
21+
if c.isdigit():
22+
current_number = current_number * 10 + int(c)
23+
24+
# Process operators and the last number
25+
if not c.isdigit() and c != ' ' or i == len(s) - 1:
26+
if operation == '+':
27+
stack.append(current_number)
28+
elif operation == '-':
29+
stack.append(-current_number)
30+
elif operation == '*':
31+
stack.append(stack.pop() * current_number)
32+
elif operation == '/':
33+
stack.append(int(stack.pop() / current_number)) # Cast to int for truncation towards zero
34+
35+
operation = c # Update the operation
36+
current_number = 0 # Reset the current number
37+
38+
# Sum up all the values in the stack
39+
return sum(stack)
40+
```
41+

python/binary_tree_cameras.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# 968. [Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/)
2+
3+
## Approach 1: Greedy Approach with Recursion
4+
5+
### Solution
6+
```python
7+
# Time Complexity: O(n)
8+
# Space Complexity: O(h) where h is the height of the tree (recursion stack)
9+
class Solution:
10+
def __init__(self):
11+
self.cameras = 0
12+
13+
def minCameraCover(self, root: TreeNode) -> int:
14+
# If root returns 0, it means it needs a camera
15+
return self.dfs(root) == 0 and self.cameras + 1 or self.cameras
16+
17+
def dfs(self, node: TreeNode) -> int:
18+
if not node:
19+
return 1 # This node is covered
20+
21+
left = self.dfs(node.left)
22+
right = self.dfs(node.right)
23+
24+
if left == 0 or right == 0:
25+
self.cameras += 1
26+
return 2 # Placing a camera at this node
27+
28+
return 1 if left == 2 or right == 2 else 0
29+
# 2 indicates child has a camera, 1 means this node is covered
30+
# 0 indicates this node needs a camera
31+
32+
class TreeNode:
33+
def __init__(self, x):
34+
self.val = x
35+
self.left = None
36+
self.right = None
37+
```
38+
39+
## Approach 2: Dynamic Programming with State Tracking
40+
41+
### Solution
42+
```python
43+
# Time Complexity: O(n)
44+
# Space Complexity: O(n)
45+
class Solution:
46+
HAS_CAMERA = 0
47+
COVERED = 1
48+
NEEDS_CAMERA = 2
49+
50+
def minCameraCover(self, root: TreeNode) -> int:
51+
dp = {}
52+
53+
def dfs(node: TreeNode) -> int:
54+
if not node:
55+
return self.COVERED
56+
57+
if node not in dp:
58+
state = [None, None, None]
59+
60+
left = dfs(node.left)
61+
right = dfs(node.right)
62+
63+
if left == self.NEEDS_CAMERA or right == self.NEEDS_CAMERA:
64+
state[self.HAS_CAMERA] = dp.get(node, [0, 0, 0])[self.HAS_CAMERA] + 1
65+
dp[node] = state
66+
return self.HAS_CAMERA
67+
68+
if left == self.HAS_CAMERA or right == self.HAS_CAMERA:
69+
state[self.COVERED] = dp.get(node, [0, 0, 0])[self.COVERED]
70+
dp[node] = state
71+
return self.COVERED
72+
73+
state[self.NEEDS_CAMERA] = dp.get(node, [0, 0, 0])[self.NEEDS_CAMERA]
74+
dp[node] = state
75+
return self.NEEDS_CAMERA
76+
77+
return dp[node][0]
78+
79+
return dfs(root) == self.NEEDS_CAMERA and dp[root][self.HAS_CAMERA] + 1 or dp[root][self.HAS_CAMERA]
80+
81+
class TreeNode:
82+
def __init__(self, x):
83+
self.val = x
84+
self.left = None
85+
self.right = None
86+
```
87+
88+
Note: The second approach is a detailed version using dynamic programming concepts, but the greedy recursive version is typically more straightforward and efficient due to its optimizations for this specific problem.
89+
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# 102. [Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/)
2+
3+
## Approach 1: Breadth-First Search (Using Queue)
4+
5+
### Solution
6+
python
7+
```python
8+
# Time Complexity: O(n), where n is the number of nodes in the tree
9+
# Space Complexity: O(n) for the queue and result storage
10+
from collections import deque
11+
from typing import List, Optional
12+
13+
class TreeNode:
14+
def __init__(self, val=0, left=None, right=None):
15+
self.val = val
16+
self.left = left
17+
self.right = right
18+
19+
class Solution:
20+
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
21+
result = []
22+
if not root:
23+
return result # Return empty result if the tree is empty
24+
25+
queue = deque([root])
26+
27+
while queue:
28+
levelSize = len(queue)
29+
currentLevel = []
30+
31+
for _ in range(levelSize):
32+
currentNode = queue.popleft() # Process the current node
33+
currentLevel.append(currentNode.val)
34+
35+
if currentNode.left:
36+
queue.append(currentNode.left) # Add left child to the queue
37+
if currentNode.right:
38+
queue.append(currentNode.right) # Add right child to the queue
39+
40+
result.append(currentLevel) # Add the current level to the result
41+
42+
return result
43+
```
44+
45+
## Approach 2: Depth-First Search (Recursive)
46+
47+
### Solution
48+
python
49+
```python
50+
# Time Complexity: O(n), where n is the number of nodes in the tree
51+
# Space Complexity: O(h), where h is the height of the tree for recursion stack
52+
from typing import List, Optional
53+
54+
class TreeNode:
55+
def __init__(self, val=0, left=None, right=None):
56+
self.val = val
57+
self.left = left
58+
self.right = right
59+
60+
class Solution:
61+
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
62+
result = []
63+
self.dfs(root, 0, result)
64+
return result
65+
66+
def dfs(self, node: Optional[TreeNode], level: int, result: List[List[int]]):
67+
if not node:
68+
return # Base case: if the node is null, return
69+
70+
if level == len(result):
71+
result.append([]) # Create a new level in the result
72+
73+
result[level].append(node.val) # Add the current node's value to the current level
74+
75+
self.dfs(node.left, level + 1, result) # Recurse for the left child
76+
self.dfs(node.right, level + 1, result) # Recurse for the right child
77+
```
78+
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# 787. [Cheapest Flights Within K Stops](https://leetcode.com/problems/cheapest-flights-within-k-stops/)
2+
3+
## Approach 1: DFS with Pruning
4+
5+
### Solution
6+
```python
7+
# Time Complexity: O(n^k) in the worst case
8+
# Space Complexity: O(n)
9+
from collections import defaultdict
10+
11+
class Solution:
12+
def __init__(self):
13+
self.result = float('inf')
14+
15+
def findCheapestPrice(self, n, flights, src, dst, K):
16+
# Create adjacency map for graph edges
17+
graph = defaultdict(dict)
18+
for u, v, price in flights:
19+
graph[u][v] = price
20+
21+
# Perform DFS
22+
self.dfs(graph, src, dst, K + 1, 0)
23+
24+
return -1 if self.result == float('inf') else self.result
25+
26+
def dfs(self, graph, node, dst, stops, cost):
27+
if node == dst:
28+
self.result = cost
29+
return
30+
31+
if stops == 0:
32+
return # No more stops available
33+
34+
if node not in graph:
35+
return # No outgoing flights
36+
37+
for neighbor, price in graph[node].items():
38+
# Pruning: proceed only if this path is cheaper than the best found so far
39+
if cost + price > self.result:
40+
continue
41+
42+
self.dfs(graph, neighbor, dst, stops - 1, cost + price)
43+
```
44+
45+
## Approach 2: Bellman-Ford Algorithm
46+
47+
### Solution
48+
```python
49+
# Time Complexity: O(K * E), where E is the number of edges
50+
# Space Complexity: O(n)
51+
import sys
52+
53+
class Solution:
54+
def findCheapestPrice(self, n, flights, src, dst, K):
55+
prices = [sys.maxsize] * n
56+
prices[src] = 0
57+
58+
# Relax the edges up to K+1 times
59+
for _ in range(K + 1):
60+
temp_prices = prices[:]
61+
for u, v, price in flights:
62+
if prices[u] == sys.maxsize:
63+
continue
64+
65+
if prices[u] + price < temp_prices[v]:
66+
temp_prices[v] = prices[u] + price
67+
prices = temp_prices
68+
69+
return -1 if prices[dst] == sys.maxsize else prices[dst]
70+
```
71+
72+
## Approach 3: Dijkstra's Algorithm with Priority Queue
73+
74+
### Solution
75+
```python
76+
# Time Complexity: O(E + VlogV), where E is the number of edges and V is the number of vertices
77+
# Space Complexity: O(n)
78+
import heapq
79+
from collections import defaultdict
80+
81+
class Solution:
82+
def findCheapestPrice(self, n, flights, src, dst, K):
83+
# Create an adjacency list for the graph
84+
graph = defaultdict(list)
85+
for u, v, price in flights:
86+
graph[u].append((v, price))
87+
88+
# Priority queue will hold entries of (cost, node, stops remaining)
89+
pq = [(0, src, K + 1)]
90+
91+
while pq:
92+
cost, node, stops_remaining = heapq.heappop(pq)
93+
94+
if node == dst:
95+
return cost
96+
97+
if stops_remaining > 0:
98+
if node not in graph:
99+
continue
100+
for next_node, price_to_next in graph[node]:
101+
heapq.heappush(pq, (cost + price_to_next, next_node, stops_remaining - 1))
102+
103+
return -1 # No valid path found
104+
```
105+

0 commit comments

Comments
 (0)