Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions clone-graph/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""
Constraints:
- The number of nodes in the graph is in the range [0, 100].
- 1 <= Node.val <= 100
- Node.val is unique for each node.
- There are no repeated edges and no self-loops in the graph.
- The Graph is connected and all nodes can be visited starting from the given node.

Shallow Copy (얕은 복사):
- 노드 자체는 새로운 메모리에 복사
- 하지만 neighbors는 원본 노드의 neighbors를 그대로 참조
예시) 원본 Node1이 Node2를 neighbor로 가질 때
복사한 CopyNode1은 새로운 노드지만
CopyNode1의 neighbor는 원본의 Node2를 그대로 가리킴

Deep Copy (깊은 복사):
- 노드는 새로운 메모리에 복사
- neighbors도 모두 새로운 노드로 복사해서 연결
예시) 원본 Node1이 Node2를 neighbor로 가질 때
CopyNode1도 새로운 노드이고
CopyNode1의 neighbor도 새로 만든 CopyNode2를 가리킴

Time Complexity: O(N + E)
- N: 노드의 개수
- E: 엣지의 개수
- 모든 노드와 엣지를 한 번씩 방문

Space Complexity: O(N)
- N: 노드의 개수
- dictionary와 재귀 호출 스택 공간

# 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 []

참고 사항:
- 혼자 풀기 어려워서, 문제와 답을 이해하는 것에 집중했습니다!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문제 풀이가 너무 어렵다고 느껴지는 경우에는 빠르게 답을 이해하고 풀어보는걸 반복하는게 도움이 된다고 생각합니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TonyKim9401 님 좋은 팁 감사합니다!

"""
class Solution:
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
if not node:
return None

dict = {}

def dfs(node):
if node.val in dict: # 이미 복사한 노드라면
return dict[node.val] # 해당 복사본 반환

# 새로운 노드 생성
copy = Node(node.val)
dict[node.val] = copy # dictionary에 기록

# 각 neighbor에 대해서도 같은 과정 수행
for neighbor in node.neighbors:
copy.neighbors.append(dfs(neighbor))

return copy

return dfs(node)

34 changes: 34 additions & 0 deletions longest-common-subsequence/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""
Constraints:
- 1 <= text1.length, text2.length <= 1000
- text1 and text2 consist of only lowercase English characters.

Time Complexity: O(m*n)
- m은 text1의 길이, n은 text2의 길이
- @cache로 중복 계산을 방지하여 각 (i,j) 조합을 한 번만 계산함

Space Complexity: O(m*n)
- 최악의 경우 호출 스택이 두 문자열 길이의 곱만큼 깊어짐

풀이방법:
1. DFS와 메모이제이션을 사용
2. 각 위치 (i,j)에서:
- 문자가 같으면: 현재 문자를 포함(+1)하고 양쪽 다음으로 이동
- 다르면: 한쪽만 이동한 경우 중 최댓값 선택
3. base case: 어느 한쪽 문자열 끝에 도달하면 종료
"""

from functools import cache
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
@cache
def dfs(i, j):
if i == len(text1) or j == len(text2):
return 0

if text1[i] == text2[j]:
return 1 + dfs(i + 1, j + 1)

return max(dfs(i + 1, j), dfs(i, j + 1))

return dfs(0, 0)
39 changes: 39 additions & 0 deletions longest-repeating-character-replacement/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
Constraints:
- 1 <= s.length <= 10^5
- s consists of only uppercase English letters.
- 0 <= k <= s.length

Time Complexity: O(n)
- 여기서 n은 문자열의 길이

Space Complexity: O(1)
- 추가 변수(left, right, max_length 등)는 상수 개

풀이방법:
1. Sliding Window로 구간을 관리
- right 포인터로 구간을 늘리다가
- 변경해야하는 문자 수가 k를 초과하면 left 포인터로 구간을 줄임

2. 각 구간에서:
- 가장 많이 등장한 문자로 나머지를 변경
- (구간 길이 - 가장 많이 등장한 문자 수)가 k 이하여야 함
"""
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
counter = {}
left = 0
max_length = 0

for right in range(len(s)):
counter[s[right]] = counter.get(s[right], 0) + 1

curr_length = right - left + 1

if curr_length - max(counter.values()) > k:
counter[s[left]] -= 1
left += 1

max_length = max(max_length, right - left + 1)

return max_length
18 changes: 18 additions & 0 deletions number-of-1-bits/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
Constraints:
- 1 <= n <= 2^31 - 1

Time Complexity: O(k)
- 여기서 k는 입력의 비트 수
- 이 경우 32비트 정수이므로 실질적으로 O(1) (항상 최대 32번 반복하기 때문)

Space Complexity: O(1)
- count 변수만 사용하므로 상수 공간 복잡도
"""
class Solution:
def hammingWeight(self, n: int) -> int:
count = 0
while n:
count += n & 1 # 현재 마지막 비트가 1인지 확인
n >>= 1 # 다음 비트 검사를 위해 오른쪽 시프트
return count