Skip to content

Commit 97d65df

Browse files
committed
[bhyun-kim, 김병현] Week 10 solutions
1 parent 42c41cd commit 97d65df

File tree

5 files changed

+240
-0
lines changed

5 files changed

+240
-0
lines changed

graph-valid-tree/bhyun-kim.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""
2+
261. Graph Valid Tree
3+
https://leetcode.com/problems/graph-valid-tree/
4+
5+
Solution:
6+
To solve this problem, we can use the depth-first search (DFS) algorithm.
7+
We can create an adjacency list to represent the graph.
8+
Then, we can perform a DFS starting from node 0 to check if all nodes are visited.
9+
If all nodes are visited, we return True; otherwise, we return False.
10+
11+
Time complexity: O(n)
12+
- We visit each node once.
13+
- The DFS has a time complexity of O(n).
14+
15+
Space complexity: O(n)
16+
- We use an adjacency list to store the graph.
17+
- The space complexity is O(n) for the adjacency list.
18+
"""
19+
20+
21+
from typing import List
22+
23+
24+
class Solution:
25+
def validTree(self, n: int, edges: List[List[int]]) -> bool:
26+
if len(edges) != n - 1:
27+
return False
28+
29+
# Initialize adjacency list
30+
graph = {i: [] for i in range(n)}
31+
for a, b in edges:
32+
graph[a].append(b)
33+
graph[b].append(a)
34+
35+
# Function to perform DFS
36+
def dfs(node, parent):
37+
visited.add(node)
38+
for neighbor in graph[node]:
39+
if neighbor == parent:
40+
continue
41+
if neighbor in visited or not dfs(neighbor, node):
42+
return False
43+
return True
44+
45+
visited = set()
46+
47+
# Start DFS from node 0
48+
if not dfs(0, -1):
49+
return False
50+
51+
# Check if all nodes are visited
52+
return len(visited) == n

house-robber-ii/bhyun-kim.py

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
213. House Robber II
3+
https://leetcode.com/problems/house-robber-ii/
4+
5+
Solution:
6+
To solve this problem, we can use the dynamic programming approach.
7+
We can create a helper function to solve the house robber problem for a given range of houses.
8+
We consider two cases:
9+
- Rob houses from 0 to n-2.
10+
- Rob houses from 1 to n-1.
11+
We return the maximum amount of money that can be robbed from these two cases.
12+
13+
Time complexity: O(n)
14+
- We iterate through each house once.
15+
- The helper function has a time complexity of O(n).
16+
17+
Space complexity: O(n)
18+
- We use a dynamic programming array to store the maximum amount of money that can be robbed.
19+
- The space complexity is O(n) for the dynamic programming array.
20+
21+
"""
22+
23+
from typing import List
24+
25+
26+
class Solution:
27+
def rob(self, nums: List[int]) -> int:
28+
def rob_linear(houses):
29+
if not houses:
30+
return 0
31+
if len(houses) == 1:
32+
return houses[0]
33+
dp = [0] * len(houses)
34+
dp[0] = houses[0]
35+
dp[1] = max(houses[0], houses[1])
36+
for i in range(2, len(houses)):
37+
dp[i] = max(dp[i - 1], houses[i] + dp[i - 2])
38+
return dp[-1]
39+
40+
n = len(nums)
41+
if n == 1:
42+
return nums[0]
43+
if n == 2:
44+
return max(nums[0], nums[1])
45+
46+
# Case 1: Rob houses from 0 to n-2
47+
case1 = rob_linear(nums[:-1])
48+
# Case 2: Rob houses from 1 to n-1
49+
case2 = rob_linear(nums[1:])
50+
51+
return max(case1, case2)

house-robber/bhyun-kim.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
198. House Robber
3+
https://leetcode.com/problems/house-robber/
4+
5+
Solution:
6+
To solve this problem, we can use the dynamic programming approach.
7+
We can create a dynamic programming array to store the maximum amount of money that can be robbed.
8+
We consider two cases:
9+
- Rob the current house and the house two steps back.
10+
- Skip the current house and rob the house one step back.
11+
We return the maximum amount of money that can be robbed from these two cases.
12+
13+
Time complexity: O(n)
14+
- We iterate through each house once.
15+
- The dynamic programming array has a time complexity of O(n).
16+
17+
Space complexity: O(n)
18+
- We use a dynamic programming array to store the maximum amount of money that can be robbed.
19+
- The space complexity is O(n) for the dynamic programming array.
20+
"""
21+
22+
from typing import List
23+
24+
25+
class Solution:
26+
def rob(self, nums: List[int]) -> int:
27+
if not nums:
28+
return 0
29+
if len(nums) == 1:
30+
return nums[0]
31+
32+
n = len(nums)
33+
dp = [0] * n
34+
dp[0] = nums[0]
35+
dp[1] = max(nums[0], nums[1])
36+
37+
for i in range(2, n):
38+
dp[i] = max(dp[i - 1], nums[i] + dp[i - 2])
39+
40+
return dp[-1]
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
5. Longest Palindromic Substring
3+
https://leetcode.com/problems/longest-palindromic-substring/
4+
5+
Solution:
6+
To solve this problem, we can use the expand from center approach.
7+
We can iterate through each character in the string and expand around it to find palindromes.
8+
We handle both odd-length and even-length palindromes by checking two cases.
9+
We return the longest palindrome found.
10+
11+
Time complexity: O(n^2)
12+
- We iterate through each character in the string.
13+
- For each character, we expand around it to find palindromes.
14+
15+
Space complexity: O(1)
16+
- We use constant space to store the maximum palindrome found.
17+
18+
"""
19+
20+
21+
class Solution:
22+
def longestPalindrome(self, s: str) -> str:
23+
if len(s) <= 1:
24+
return s
25+
26+
def expand_from_center(left, right):
27+
while left >= 0 and right < len(s) and s[left] == s[right]:
28+
left -= 1
29+
right += 1
30+
return s[left + 1 : right]
31+
32+
max_str = s[0]
33+
34+
for i in range(len(s) - 1):
35+
odd = expand_from_center(i, i)
36+
even = expand_from_center(i, i + 1)
37+
38+
if len(odd) > len(max_str):
39+
max_str = odd
40+
if len(even) > len(max_str):
41+
max_str = even
42+
43+
return max_str
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""
2+
323. Number of Connected Components in an Undirected Graph
3+
https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/
4+
5+
Solution:
6+
To solve this problem, we can use the depth-first search (DFS) algorithm.
7+
We can create an adjacency list to represent the graph.
8+
Then, we can perform a DFS starting from each node to count the number of connected components.
9+
We keep track of visited nodes to avoid revisiting nodes.
10+
The number of connected components is the number of times we perform DFS.
11+
12+
Time complexity: O(n+m)
13+
- We visit each node and edge once.
14+
- The DFS has a time complexity of O(n+m).
15+
16+
Space complexity: O(n+m)
17+
- We use an adjacency list to store the graph.
18+
- The space complexity is O(n+m) for the adjacency list and visited set.
19+
20+
"""
21+
22+
from typing import List
23+
24+
25+
class Solution:
26+
def countComponents(self, n: int, edges: List[List[int]]) -> int:
27+
# Initialize the graph as an adjacency list
28+
graph = {i: [] for i in range(n)}
29+
for a, b in edges:
30+
graph[a].append(b)
31+
graph[b].append(a)
32+
33+
# Set to keep track of visited nodes
34+
visited = set()
35+
36+
# Function to perform DFS
37+
def dfs(node):
38+
stack = [node]
39+
while stack:
40+
current = stack.pop()
41+
for neighbor in graph[current]:
42+
if neighbor not in visited:
43+
visited.add(neighbor)
44+
stack.append(neighbor)
45+
46+
# Count connected components
47+
count = 0
48+
for i in range(n):
49+
if i not in visited:
50+
count += 1
51+
visited.add(i)
52+
dfs(i)
53+
54+
return count

0 commit comments

Comments
 (0)