Skip to content

[Lyla] Week 09 #995

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 4 commits into from
Feb 9, 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
22 changes: 22 additions & 0 deletions find-minimum-in-rotated-sorted-array/pmjuu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'''
시간 복잡도: O(log n)
- 이진 탐색을 사용하여 매 반복마다 검색 범위를 절반으로 줄이므로 O(log n)입니다.

공간 복잡도: O(1)
- 추가적인 배열이나 리스트를 사용하지 않고, 몇 개의 변수만 사용하므로 O(1)입니다.
'''

from typing import List

class Solution:
def findMin(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1

while left < right:
mid = (left + right) // 2
if nums[mid] > nums[right]:
left = mid + 1 # 최소값이 오른쪽에 있음
else:
right = mid # 최소값이 mid 또는 왼쪽에 있음

return nums[left]
28 changes: 28 additions & 0 deletions linked-list-cycle/pmjuu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'''
시간 복잡도: O(n)
- `fast`와 `slow` 포인터가 리스트를 한 번 순회하면서 주어진 연결 리스트의 길이에 비례하는 작업을 수행합니다.
- 따라서 최악의 경우 모든 노드를 한 번씩 방문하게 되므로 O(n)입니다.

공간 복잡도: O(1)
- 추가적인 자료구조를 사용하지 않고, `fast`와 `slow`라는 두 개의 포인터만 사용하므로 O(1)입니다.
'''
from typing import Optional
# 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:
fast = head
slow = head

while fast and fast.next:
fast = fast.next.next
slow = slow.next

if fast == slow:
return True

return False
24 changes: 24 additions & 0 deletions maximum-product-subarray/pmjuu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'''
시간 복잡도: O(n)
- 리스트를 한 번 순회하면서 각 요소에 대해 최대값과 최소값을 갱신하므로 O(n)입니다.

공간 복잡도: O(1)
- 추가적인 배열을 사용하지 않고, 몇 개의 변수만 사용하므로 O(1)입니다.
'''

from typing import List

class Solution:
def maxProduct(self, nums: List[int]) -> int:
n = len(nums)
max_product = nums[0]
cur_max = nums[0] # 현재 위치까지 최대 곱
cur_min = nums[0] # 현재 위치까지 최소 곱 (음수 대비)

for i in range(1, n):
temp_max = cur_max
cur_max = max(nums[i], cur_max * nums[i], cur_min * nums[i])
cur_min = min(nums[i], temp_max * nums[i], cur_min * nums[i])
max_product = max(max_product, cur_max)

return max_product
71 changes: 71 additions & 0 deletions pacific-atlantic-water-flow/pmjuu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'''
시간 복잡도: O(m * n)
- 각 바다에서 BFS를 한 번씩 수행하며, 각 셀을 최대 한 번씩 방문하므로 O(m * n)입니다.

공간 복잡도: O(m * n)
- BFS 탐색을 위한 큐와 방문한 셀을 저장하는 집합(set)이 필요하므로 O(m * n)입니다.
'''

from collections import deque
from typing import List

class Solution:
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
m, n = len(heights), len(heights[0])
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]

def bfs(starts):
queue = deque(starts)
reachable = set(starts)

while queue:
r, c = queue.popleft()
for dr, dc in directions:
nr, nc = r + dr, c + dc
if (0 <= nr < m and 0 <= nc < n and
(nr, nc) not in reachable and
heights[nr][nc] >= heights[r][c]): # 물이 흐를 수 있는지 확인
queue.append((nr, nc))
reachable.add((nr, nc))

return reachable

# 태평양(왼쪽과 위쪽 가장자리)에서 시작하는 셀들
pacific_starts = [(0, c) for c in range(n)] + [(r, 0) for r in range(m)]
# 대서양(오른쪽과 아래쪽 가장자리)에서 시작하는 셀들
atlantic_starts = [(m-1, c) for c in range(n)] + [(r, n-1) for r in range(m)]

pacific_reach = bfs(pacific_starts)
atlantic_reach = bfs(atlantic_starts)

return list(pacific_reach & atlantic_reach)


class Solution:
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
if not heights or not heights[0]:
return []

m, n = len(heights), len(heights[0])
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]

def dfs(r, c, reachable):
reachable.add((r, c))
for dr, dc in directions:
nr, nc = r + dr, c + dc
if (0 <= nr < m and 0 <= nc < n and
(nr, nc) not in reachable and
heights[nr][nc] >= heights[r][c]):
dfs(nr, nc, reachable)

pacific_reach, atlantic_reach = set(), set()

for c in range(n):
dfs(0, c, pacific_reach)
dfs(m-1, c, atlantic_reach)

for r in range(m):
dfs(r, 0, pacific_reach)
dfs(r, n-1, atlantic_reach)

return list(pacific_reach & atlantic_reach)