-
-
Notifications
You must be signed in to change notification settings - Fork 361
[yuseok89] WEEK 08 Solutions #2813
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4b9eb36
00826e8
015ee6c
887a9ff
5ef2d53
935c0f7
9454135
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # TC: O(N) | ||
| # SC: O(N) | ||
| """ | ||
| # Definition for a Node. | ||
| class Node: | ||
| def __init__(self, val = 0, neighbors = None): | ||
| self.val = val | ||
| self.neighbors = neighbors if neighbors is not None else [] | ||
| """ | ||
|
|
||
| from typing import Optional | ||
| class Solution: | ||
| def cloneGraph(self, node: Optional['Node']) -> Optional['Node']: | ||
|
|
||
| visited = {} | ||
|
|
||
| def rec(node: Optional['Node']) -> Optional['Node']: | ||
|
|
||
| if not node: | ||
| return None | ||
|
|
||
| if node.val in visited: | ||
| return visited[node.val] | ||
|
|
||
| return_val = Node(node.val) | ||
| visited[node.val] = return_val | ||
|
|
||
| for neighbor in node.neighbors: | ||
| cloned = rec(neighbor) | ||
|
|
||
| if cloned: | ||
| return_val.neighbors.append(cloned) | ||
|
|
||
| return return_val | ||
|
|
||
| return rec(node) | ||
|
|
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석longest-common-subsequence/yuseok89.py# TC: O(N*M)
# SC: O(N*M)
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
n = len(text1)
m = len(text2)
dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
for i in range(n):
for j in range(m):
if text1[i] == text2[j]:
dp[i + 1][j + 1] = dp[i][j] + 1
else:
dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j])
return dp[n][m]
📊 시간/공간 복잡도 분석
피드백: 2D DP 배열을 사용해 모든 부분문자열 조합을 점화식을 통해 계산합니다. 개선 제안: 현재 구현이 적절해 보입니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 깔끔한 해결 잘 봤습니다!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 의견 감사합니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 이런 방식도 엄청 깔끔하네요, 저도 배우고 갑니다!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석longest-common-subsequence/yuseok89.py# TC: O(N*M)
# SC: O(N)
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
n = len(text1)
m = len(text2)
dp = [[0 for _ in range(m + 1)] for _ in range(2)]
cur, prev = 1, 0
for i in range(n):
for j in range(m):
if text1[i] == text2[j]:
dp[cur][j + 1] = dp[prev][j] + 1
else:
dp[cur][j + 1] = max(dp[prev][j + 1], dp[cur][j])
cur, prev = prev, cur
return dp[prev][m]
📊 시간/공간 복잡도 분석
피드백: 가로 방향으로 DP를 2행으로만 유지하여 공간을 줄인 풀이다. 매 이터레이션마다 현재 행과 이전 행을 번갈아 갱신한다. 개선 제안: 현재 구현이 적절해 보입니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석longest-common-subsequence/yuseok89.py# TC: O(N*M)
# SC: O(M)
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
n = len(text1)
m = len(text2)
dp = [[0 for _ in range(m + 1)] for _ in range(2)]
cur, prev = 1, 0
for i in range(n):
for j in range(m):
if text1[i] == text2[j]:
dp[cur][j + 1] = dp[prev][j] + 1
else:
dp[cur][j + 1] = max(dp[prev][j + 1], dp[cur][j])
cur, prev = prev, cur
return dp[prev][m]
📊 시간/공간 복잡도 분석
풀이 1:
|
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(N*M) | O(n * m) | ✅ |
| Space | O(M) | O(m) | ✅ |
피드백: 가로 방향과 세로 방향으로 DP 값을 교차저장하며 공간을 2개 배열로 사용하는 최적화가 적용되어 있다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Solution.longestCommonSubsequence — Time: ✅ O(N*M) → O(n * m) / Space: ✅ O(M) → O(m)
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(N*M) | O(n * m) | ✅ |
| Space | O(M) | O(m) | ✅ |
피드백: 반복문에서 두 배열만 사용해 메모리 사용을 줄였고, 인덱스 관리로 올바른 결과를 얻는다.
개선 제안: 현재 구현이 적절해 보입니다.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # TC: O(N*M) | ||
| # SC: O(M) | ||
| class Solution: | ||
| def longestCommonSubsequence(self, text1: str, text2: str) -> int: | ||
|
|
||
| n = len(text1) | ||
| m = len(text2) | ||
| dp = [[0 for _ in range(m + 1)] for _ in range(2)] | ||
|
|
||
| cur, prev = 1, 0 | ||
|
|
||
| for i in range(n): | ||
| for j in range(m): | ||
| if text1[i] == text2[j]: | ||
| dp[cur][j + 1] = dp[prev][j] + 1 | ||
| else: | ||
| dp[cur][j + 1] = max(dp[prev][j + 1], dp[cur][j]) | ||
|
|
||
| cur, prev = prev, cur | ||
|
|
||
| return dp[prev][m] | ||
|
|
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석longest-repeating-character-replacement/yuseok89.py# TC: O(N)
# SC: O(K)
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
l = 0
cnt = defaultdict(int)
m, ans = 0, 0
for r in range(len(s)):
c = s[r]
cnt[c] += 1
m = max(m, cnt[c])
while m + k < r - l + 1:
c = s[l]
l += 1
cnt[c] -= 1
if cnt[c] == m - 1:
m = max(cnt.values())
ans = max(ans, r - l + 1);
return ans
📊 시간/공간 복잡도 분석
피드백: 윈도우의 길이가 증가하는 동안 최대 빈도수를 유지해 조건을 체크합니다. 개선 제안: 현재 구현이 적절해 보입니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # TC: O(N) | ||
| # SC: O(K) | ||
| class Solution: | ||
| def characterReplacement(self, s: str, k: int) -> int: | ||
|
|
||
| l = 0 | ||
| cnt = defaultdict(int) | ||
| m, ans = 0, 0 | ||
|
|
||
| for r in range(len(s)): | ||
| c = s[r] | ||
| cnt[c] += 1 | ||
|
|
||
| m = max(m, cnt[c]) | ||
|
|
||
| while m + k < r - l + 1: | ||
| c = s[l] | ||
| l += 1 | ||
| cnt[c] -= 1 | ||
|
|
||
| if cnt[c] == m - 1: | ||
| m = max(cnt.values()) | ||
|
|
||
| ans = max(ans, r - l + 1); | ||
|
|
||
| return ans | ||
|
|
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석palindromic-substrings/yuseok89.py# TC: O(N^2)
# SC: O(1)
class Solution:
def countSubstrings(self, s: str) -> int:
ans = 0
n = len(s)
for center_idx in range(n):
idx = 0
while 0 <= center_idx - idx and center_idx + idx < n:
if s[center_idx - idx] == s[center_idx + idx]:
ans = ans + 1
else:
break
idx += 1
idx = 0
while 0 <= center_idx - idx and center_idx + idx + 1< n:
if s[center_idx - idx] == s[center_idx + idx + 1]:
ans = ans + 1
else:
break
idx += 1
return ans
📊 시간/공간 복잡도 분석
피드백: 각 센터에서 좌우로 확장하며 회문 여부를 확인합니다. 개선 제안: 현재 구현이 적절해 보입니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # TC: O(N^2) | ||
| # SC: O(1) | ||
| class Solution: | ||
| def countSubstrings(self, s: str) -> int: | ||
|
|
||
| ans = 0 | ||
| n = len(s) | ||
|
|
||
| for center_idx in range(n): | ||
|
|
||
| idx = 0 | ||
|
|
||
| while 0 <= center_idx - idx and center_idx + idx < n: | ||
| if s[center_idx - idx] == s[center_idx + idx]: | ||
| ans = ans + 1 | ||
| else: | ||
| break | ||
|
|
||
| idx += 1 | ||
|
|
||
| idx = 0 | ||
| while 0 <= center_idx - idx and center_idx + idx + 1< n: | ||
| if s[center_idx - idx] == s[center_idx + idx + 1]: | ||
| ans = ans + 1 | ||
| else: | ||
| break | ||
|
|
||
| idx += 1 | ||
|
|
||
| return ans | ||
|
|
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석reverse-bits/yuseok89.py# TC: O(K)
# SC: O(1)
class Solution:
def reverseBits(self, n: int) -> int:
ans = 0
for _ in range(32):
ans *= 2
ans += n % 2
n //= 2
return ans
📊 시간/공간 복잡도 분석
피드백: 고정된 비트 길이(32비트) 기준으로 순차적으로 반전한다. 개선 제안: 현재 구현이 적절해 보입니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # TC: O(K) | ||
| # SC: O(1) | ||
| class Solution: | ||
| def reverseBits(self, n: int) -> int: | ||
| ans = 0 | ||
|
|
||
| for _ in range(32): | ||
| ans *= 2 | ||
| ans += n % 2 | ||
| n //= 2 | ||
|
|
||
| return ans | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏷️ 알고리즘 패턴 분석
clone-graph/yuseok89.py
📊 시간/공간 복잡도 분석
피드백: 노드의 val를 키로 사용해 방문 여부를 판단하지만, 노드 간 값이 같아도 서로 다른 노드를 구별해야 할 수 있으니 id 기반 매핑이 더 안정적일 수 있습니다.
개선 제안: 현재 구현이 적절해 보입니다.