Skip to content

[yyyyyyyyyKim] WEEK 09 solutions #1520

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

Merged
merged 6 commits into from
May 31, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 23 additions & 0 deletions linked-list-cycle/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
# 시간복잡도 O(n), 공간복잡도 O(n)
# Follow up : 공간복잡도 O(1) 방식도 생각해 볼 것.

# 방문한 노드 set으로 저장
visited = set()

while head:
# 방문했던 노드라면 사이클 존재 -> True 리턴
if head in visited:
return True

visited.add(head) # 방문 노드로 저장
head = head.next # 다음 노드로 이동

return False
19 changes: 19 additions & 0 deletions maximum-product-subarray/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Solution:
def maxProduct(self, nums: List[int]) -> int:

# 연속된 부분 배열의 곱이 가장 큰 값 찾기(정수)
# DP (시간복잡도 O(n), 공간복잡도 O(1))
answer = nums[0]
prev_max = prev_min = nums[0]

for i in range(1,len(nums)):
n = nums[i]

# 음수*음수는 양수이므로 max,min 둘다 계산
curr_max = max(n,prev_max*n, prev_min*n)
Copy link
Contributor

Choose a reason for hiding this comment

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

중간 변수 2개(curr_max, curr_min) 사용하니까 훨씬 이해하기가 편하네요. 👍

curr_min = min(n,prev_max*n, prev_min*n)

answer = max(answer, curr_max) # 최대 곱 업데이트
prev_max, prev_min = curr_max, curr_min # 현재값을 이전값으로 업데이트

return answer
37 changes: 37 additions & 0 deletions minimum-window-substring/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class Solution:
def minWindow(self, s: str, t: str) -> str:
# 슬라이딩 윈도우(시간복잡도 O(m+n), 공간복잡도 O(n) : m=len(s), n=len(t))
# 필요한 문자 개수 딕셔너리로 정리
need = {}
for i in t:
need[i] = need.get(i,0) + 1

window = {} # 현재 윈도우에 포함된 문자 개수 딕셔너리로 정리
have = 0 # 조건을 만족한 문자 수
need_count = len(need) # 조건을 만족해야하는 문자 수
min_len = 100001 # 최소윈도우길이(최대값을 초기값으로 설정)
answer = ""
left = 0

# 오른쪽 포인터 이동
for right in range(len(s)):
window[s[right]] = window.get(s[right],0) + 1

# 해당 문자가 조건을 만족했다면 have += 1
if s[right] in need and window[s[right]] == need[s[right]]:
have += 1

# 모든 조건 만족하면 왼쪽 계속 줄이기
while have == need_count:
# 최소 윈도우 길이 갱신
if (right - left + 1) < min_len:
min_len = right - left + 1
answer = s[left:right+1]
Copy link
Contributor

Choose a reason for hiding this comment

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

최소 윈도우 길이 갱신할 때, answer에 해당 부분 문자열을 바로 저장해두면 마지막에 그대로 반환할 수 있어 편리하네요! 👍


# 윈도우 왼쪽 문자 제거
window[s[left]] -= 1
if s[left] in need and window[s[left]] < need[s[left]]:
have -= 1
left += 1

return answer
32 changes: 32 additions & 0 deletions pacific-atlantic-water-flow/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class Solution:
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
# *문제 이해에 시간이 많이 걸림.
# 각 칸에서 시작한 물이 태평양과 대서양 두 바다 모두로 흘러갈 수 있는 칸들 찾는 문제(높이가 같거나 낮은쪽으로만 물이 이동 가능함)
# 문제를 역으로 생각해서 바다에서 물이 올라갈 수 있는 칸(더 높거나 같은 칸) 찾기.
# DFS(시간복잡도 O(m*n), 공간복잡도 O(m*n))

m, n = len(heights), len(heights[0])
pac = set() # 태평양 갈 수 있는 칸 저장
atl = set() # 대서양 갈 수 있는 칸 저장
directions = [(-1,0), (1,0), (0,-1), (0,1)] # 상하좌우

def dfs(x, y, visited):
visited.add((x,y)) # 현재위치 방문처리

# 현재 위치에서 상하좌우 탐색
for dx, dy in directions:
nx, ny = x + dx, y + dy
# 다음 위치가 범위안이고, 아직 방문하지 않았고, 물이 흘러갈 수 있는 높이라면, 탐색
if 0 <= nx < m and 0 <= ny < n and (nx, ny) not in visited and heights[nx][ny] >= heights[x][y]:
dfs(nx, ny, visited)


for i in range(m):
dfs(i, 0, pac) # 왼쪽(pacific)
dfs(i, n-1, atl) # 오른쪽(atlantic)
for j in range(n):
dfs(0, j, pac) # 위쪽(pacific)
dfs(m-1, j, atl) # 아래쪽(atlantic)

# 교집합(태평양,대서양 모두 갈 수 있는 좌표의 교집합)
return list(pac & atl)
19 changes: 19 additions & 0 deletions sum-of-two-integers/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Solution:
def getSum(self, a: int, b: int) -> int:

# 비트 연산(보완이 필요함, python은 무제한정수를 사용하므로 mask써서 32bit 정수로 잘라줘야함)
Copy link
Contributor

Choose a reason for hiding this comment

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

Python 정수형이 오버플로우 없이 무한정 커질 수 있다는 특징을 알게 되어 좋았습니다.

mask = 0xFFFFFFFF # 32비트 정수 마스크
max_int = 0X7FFFFFFF # 양수 최대값

while b != 0:
# 자리올림(AND연산)
carry = (a&b) & mask
# 자리올림없이 더하기(XOR연산)
a = (a^b) & mask
# 왼쪽으로 1 비트이동(다음 자리에서 더할 carry값)
b = (carry << 1) & mask

# a가 음수인 경우 보수 변환
return a if a <= max_int else ~(a^mask)

# return sum([a,b])