-
-
Notifications
You must be signed in to change notification settings - Fork 361
[daehyun99] WEEK 08 Solutions #2816
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
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
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. 🏷️ 알고리즘 패턴 분석clone-graph/daehyun99.py# Time: O(N + E
# Space: 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']:
have_to_look = set()
seen = set()
copied = {}
have_to_look.add(node)
while len(have_to_look) > 0 :
curr = have_to_look.pop()
if curr is not None:
if curr.val not in copied:
copied[curr.val] = Node(curr.val, None)
for neighbor in curr.neighbors:
if neighbor.val not in copied:
copied[neighbor.val] = Node(neighbor.val, None)
if neighbor.val not in seen:
have_to_look.add(neighbor)
copied[curr.val].neighbors.append(copied[neighbor.val])
seen.add(curr.val)
return copied.get(1, None)
📊 시간/공간 복잡도 분석
피드백: 정확한 복제 노드 생성을 위한 맵과 방문 추적에 의한 탐색이다. 각 정점과 간선은 한 번씩 처리되므로 시간 복잡도는 선형이다. 개선 제안: 현재 구현은 노드 값으로 중복 여부를 판단하고 있어, 동일한 값의 서로 다른 노드가 있을 경우 의도하지 않은 동작을 유발할 수 있습니다. 노드 고유 식별자(노드 객체)를 키로 사용하는 맵으로 수정하면 안정성이 좋아집니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # Time: O(N + E | ||
| # Space: 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']: | ||
| have_to_look = set() | ||
| seen = set() | ||
| copied = {} | ||
|
|
||
| have_to_look.add(node) | ||
|
|
||
| while len(have_to_look) > 0 : | ||
| curr = have_to_look.pop() | ||
| if curr is not None: | ||
| if curr.val not in copied: | ||
| copied[curr.val] = Node(curr.val, None) | ||
| for neighbor in curr.neighbors: | ||
| if neighbor.val not in copied: | ||
| copied[neighbor.val] = Node(neighbor.val, None) | ||
| if neighbor.val not in seen: | ||
| have_to_look.add(neighbor) | ||
| copied[curr.val].neighbors.append(copied[neighbor.val]) | ||
| seen.add(curr.val) | ||
|
|
||
| return copied.get(1, None) | ||
|
|
|
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/daehyun99.py# Time: O(s)
# Space: O(s)
from collections import defaultdict
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
count = defaultdict(int)
l = 0
maxf = 0
res = 0
for r in range(len(s)):
count[s[r]] += 1
maxf = max(maxf, count[s[r]])
while (r - l + 1) - maxf > k:
count[s[l]] -= 1
l += 1
res = max(res, r - l + 1)
return res
"""
# Time: O(s)
# Space: O(s)
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
# find_bunch()
bunch = []
start_idx = 0
start_word = s[0]
for i in range(1, len(s)):
if s[i] != start_word:
bunch.append([start_word, i- start_idx])
start_word = s[i]
start_idx = i
bunch.append([start_word, len(s) - start_idx])
# find_LRCR()
unique = set([c for c in s])
result = 0
for base in unique:
changed_num = 0
left = 0
right = 0
length = 0
while right < len(bunch):
if bunch[right][0] != base:
changed_num += bunch[right][1]
length += bunch[right][1]
right += 1
while changed_num > k:
if bunch[left][0] != base:
changed_num -= bunch[left][1]
length -= bunch[left][1]
left += 1
result = max(result, min(length + k - changed_num, len(s)))
return result
"""
📊 시간/공간 복잡도 분석
피드백: 슬라이딩 윈도우 방식이 최적의 시간 복잡도를 보장하고, 딕셔너리로 문자 빈도를 관리한다. 개선 제안: 현재 구현이 적절해 보입니다.
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/daehyun99.py# Time: O(s)
# Space: O(1)from collections import defaultdict
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
count = defaultdict(int)
l = 0
maxf = 0
res = 0
for r in range(len(s)):
count[s[r]] += 1
maxf = max(maxf, count[s[r]])
while (r - l + 1) - maxf > k:
count[s[l]] -= 1
l += 1
res = max(res, r - l + 1)
return res
"""
# Time: O(s)
# Space: O(s)
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
# find_bunch()
bunch = []
start_idx = 0
start_word = s[0]
for i in range(1, len(s)):
if s[i] != start_word:
bunch.append([start_word, i- start_idx])
start_word = s[i]
start_idx = i
bunch.append([start_word, len(s) - start_idx])
# find_LRCR()
unique = set([c for c in s])
result = 0
for base in unique:
changed_num = 0
left = 0
right = 0
length = 0
while right < len(bunch):
if bunch[right][0] != base:
changed_num += bunch[right][1]
length += bunch[right][1]
right += 1
while changed_num > k:
if bunch[left][0] != base:
changed_num -= bunch[left][1]
length -= bunch[left][1]
left += 1
result = max(result, min(length + k - changed_num, len(s)))
return result
"""
📊 시간/공간 복잡도 분석
풀이 1:
|
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(s) | O(n) | ❌ |
| Space | O(1) | O(1) | ✅ |
피드백: 한 종류의 문자로 맞출 수 있는 최대 길이를 유지하기 위해 창의 최대 등장 횟수를 추적한다. 불필요한 중간 데이터는 제거되어 있다.
개선 제안: 제공된 두 번째 구현은 복잡도가 증가하며 불필요한 배열 조작이 많아 보입니다. 첫 번째 구현처럼 간단한 슬라이딩 윈도우 기법으로 통일하는 것이 좋습니다.
풀이 2: Solution.characterReplacement — Time: ❌ O(s) → O(n) / Space: ❌ O(s) → O(1)
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(s) | O(n) | ❌ |
| Space | O(s) | O(1) | ❌ |
피드백: 부분 문자열을 문자별로 분리해 처리하는 방식은 복잡도가 증가하고 구현 난이도가 높습니다.
개선 제안: 가능하면 단일 일관된 접근 방식으로 구현하여 시간/공간 복잡도를 명확히 하는 것이 좋습니다.
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.
🏷️ 알고리즘 패턴 분석
longest-repeating-character-replacement/daehyun99.py
# Time: O(n)
# Space: O(1)
from collections import defaultdict
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
count = defaultdict(int)
l = 0
maxf = 0
res = 0
for r in range(len(s)):
count[s[r]] += 1
maxf = max(maxf, count[s[r]])
while (r - l + 1) - maxf > k:
count[s[l]] -= 1
l += 1
res = max(res, r - l + 1)
return res
"""
# Time: O(n)
# Space: O(1)
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
# find_bunch()
bunch = []
start_idx = 0
start_word = s[0]
for i in range(1, len(s)):
if s[i] != start_word:
bunch.append([start_word, i- start_idx])
start_word = s[i]
start_idx = i
bunch.append([start_word, len(s) - start_idx])
# find_LRCR()
unique = set([c for c in s])
result = 0
for base in unique:
changed_num = 0
left = 0
right = 0
length = 0
while right < len(bunch):
if bunch[right][0] != base:
changed_num += bunch[right][1]
length += bunch[right][1]
right += 1
while changed_num > k:
if bunch[left][0] != base:
changed_num -= bunch[left][1]
length -= bunch[left][1]
left += 1
result = max(result, min(length + k - changed_num, len(s)))
return result
"""- 패턴: Sliding Window, Greedy, Hash Map / Hash Set
- 설명: 주 코드 1은 슬라이딩 윈도우로 부분 문자열의 길이를 확장/수축하며 최대 대체 수를 추적한다. 또한 각 문자 등장 횟수를 세는 해시 맵을 사용하고, 조건 만족 시 윈도우를 이동하는 점에서 Greedy 성격이 보인다. 해시 맵을 활용해 문자 빈도 추적이 핵심이다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(1) |
피드백: 한 번의 패스에서 현재 윈도우의 최대 등장 문자 수를 추적하여 조건을 검사한다. 해시맵을 이용해 문자 빈도수를 관리한다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Time: O(n) | ||
| # Space: O(1) | ||
| from collections import defaultdict | ||
| class Solution: | ||
| def characterReplacement(self, s: str, k: int) -> int: | ||
| count = defaultdict(int) | ||
|
|
||
| l = 0 | ||
| maxf = 0 | ||
| res = 0 | ||
| for r in range(len(s)): | ||
| count[s[r]] += 1 | ||
| maxf = max(maxf, count[s[r]]) | ||
|
|
||
| while (r - l + 1) - maxf > k: | ||
| count[s[l]] -= 1 | ||
| l += 1 | ||
| res = max(res, r - l + 1) | ||
| return res | ||
|
|
||
| """ | ||
| # Time: O(n) | ||
| # Space: O(1) | ||
| class Solution: | ||
| def characterReplacement(self, s: str, k: int) -> int: | ||
| # find_bunch() | ||
| bunch = [] | ||
| start_idx = 0 | ||
| start_word = s[0] | ||
| for i in range(1, len(s)): | ||
| if s[i] != start_word: | ||
| bunch.append([start_word, i- start_idx]) | ||
| start_word = s[i] | ||
| start_idx = i | ||
| bunch.append([start_word, len(s) - start_idx]) | ||
|
|
||
| # find_LRCR() | ||
| unique = set([c for c in s]) | ||
| result = 0 | ||
|
|
||
| for base in unique: | ||
| changed_num = 0 | ||
| left = 0 | ||
| right = 0 | ||
| length = 0 | ||
| while right < len(bunch): | ||
| if bunch[right][0] != base: | ||
| changed_num += bunch[right][1] | ||
| length += bunch[right][1] | ||
| right += 1 | ||
|
|
||
| while changed_num > k: | ||
| if bunch[left][0] != base: | ||
| changed_num -= bunch[left][1] | ||
| length -= bunch[left][1] | ||
| left += 1 | ||
| result = max(result, min(length + k - changed_num, len(s))) | ||
| return result | ||
| """ |
|
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/daehyun99.pyclass Solution:
def countSubstrings(self, s: str) -> int:
result = 0
# odd
for i in range(0, len(s)):
m, n = i, i
while 0 <= m and n < len(s) and s[m] == s[n]:
result += 1
m -= 1
n += 1
# even
for i in range(0, len(s)-1):
m, n = i, i+1
while 0 <= m and n < len(s) and s[m] == s[n]:
result += 1
m -= 1
n += 1
return result
📊 시간/공간 복잡도 분석
피드백: 공간은 상수이며 시간은 모든 중심에서 확장하는 방식으로 계산한다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| class Solution: | ||
| def countSubstrings(self, s: str) -> int: | ||
| result = 0 | ||
|
|
||
| # odd | ||
| for i in range(0, len(s)): | ||
| m, n = i, i | ||
| while 0 <= m and n < len(s) and s[m] == s[n]: | ||
| result += 1 | ||
| m -= 1 | ||
| n += 1 | ||
|
|
||
| # even | ||
| for i in range(0, len(s)-1): | ||
| m, n = i, i+1 | ||
| while 0 <= m and n < len(s) and s[m] == s[n]: | ||
| result += 1 | ||
| m -= 1 | ||
| n += 1 | ||
| return result | ||
|
|
||
|
|
||
|
|
|
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/daehyun99.pyclass Solution:
def reverseBits(self, n: int) -> int:
res = 0
for i in range(32):
bit = (n >> i) & 1
res += (bit << (31 - i))
return res
📊 시간/공간 복잡도 분석
피드백: 정수의 각 비트를 순차적으로 뒤집어 최종 값을 구성한다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| class Solution: | ||
| def reverseBits(self, n: int) -> int: | ||
| res = 0 | ||
| for i in range(32): | ||
| bit = (n >> i) & 1 | ||
| res += (bit << (31 - i)) | ||
| return res |
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/daehyun99.py
📊 시간/공간 복잡도 분석
풀이 1:
Solution.cloneGraph— Time: O(N + E) / Space: O(N)피드백: 노드 고유 식별자로 val 을 사용해 복제, 해시맵으로 매핑하지만 노드 객체가 중복될 수 있어 실제 구현에서 id 기반 매핑이 더 안전하다.
개선 제안: 고려해볼 만한 대안: 노드 객체 자체를 키로 매핑하고, 각 노드의 객체를 직접 참조하는 방식으로 구현하면 중복 문제를 피할 수 있다.
풀이 2:
Solution.cloneGraph— Time: O(N + E) / Space: O(N)피드백: 현재 구현은 노드 값을 키로 사용해 복제 노드를 저장하지만, 그래프에 같은 값의 노드가 여러 개 있을 수 있는 경우 문제가 생길 수 있다.
개선 제안: 고려해볼 만한 대안: 노드 객체를 직접 키로 사용하고, 깊이/너비 우선 탐색으로 실제 Node 객체 간의 매핑을 유지하도록 재구현.