Skip to content

Commit aa22639

Browse files
authored
Merge pull request #982 from KwonNayeon/main
[KwonNayeon] Week 9
2 parents 532fe03 + 5140ffd commit aa22639

File tree

5 files changed

+239
-0
lines changed

5 files changed

+239
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
Constraints:
3+
- n == nums.length
4+
- 1 <= n <= 5000
5+
- -5000 <= nums[i] <= 5000
6+
- All the integers of nums are unique.
7+
- nums is sorted and rotated between 1 and n times.
8+
9+
Time Complexity: O(log n)
10+
- 이진 탐색을 사용하므로 매 단계마다 탐색 범위가 절반으로 줄어듦
11+
12+
Space Complexity: O(1)
13+
- 추가 공간을 사용하지 않고 포인터만 사용
14+
15+
풀이방법:
16+
1. 이진 탐색(Binary Search) 활용
17+
2. mid와 right 값을 비교하여 조건을 나눔
18+
- Case 1: nums[mid] > nums[right]
19+
- 오른쪽 부분이 정렬되어 있지 않음
20+
- 최솟값은 mid 오른쪽에 존재
21+
- left = mid + 1
22+
- Case 2: nums[mid] <= nums[right]
23+
- mid부터 right까지는 정렬되어 있음
24+
- 최솟값은 mid를 포함한 왼쪽에 존재 가능
25+
- right = mid
26+
"""
27+
28+
class Solution:
29+
def findMin(self, nums: List[int]) -> int:
30+
left = 0
31+
right = len(nums) - 1
32+
33+
while left < right:
34+
mid = (left + right) // 2
35+
36+
if nums[mid] > nums[right]:
37+
left = mid + 1
38+
39+
else:
40+
right = mid
41+
42+
return nums[left]

linked-list-cycle/KwonNayeon.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""
2+
Constraints:
3+
- The number of the nodes in the list is in the range [0, 10^4]
4+
- -10^5 <= Node.val <= 10^5
5+
- pos is -1 or a valid index in the linked-list
6+
7+
Time Complexity:
8+
- Solution 1: O(n)
9+
- Solution 2: O(n)
10+
11+
Space Complexity:
12+
- Solution 1: O(n) - visited set에 모든 노드를 저장할 수 있음
13+
- Solution 2: O(1) - 추가 메모리 사용하지 않음
14+
15+
풀이방법:
16+
1. 처음엔 직관적인 방법으로 해결, 한 번 마주친 노드를 다시 만나는지를 체크하는 방식
17+
2. slow, fast 두 개의 노드를 활용, 만약 cycle이 존재하는 경우 fast가 slow와 언젠가 만나게 됨,
18+
만약 cycle이 없다면 둘은 만나지 않음
19+
"""
20+
21+
# Definition for singly-linked list.
22+
# class ListNode:
23+
# def __init__(self, x):
24+
# self.val = x
25+
# self.next = None
26+
27+
# Solution 1: 한 번 마주친 노드를 다시 만나는지를 체크
28+
class Solution:
29+
def hasCycle(self, head: Optional[ListNode]) -> bool:
30+
visited = set()
31+
32+
current = head
33+
while current:
34+
if current in visited:
35+
return True
36+
visited.add(current)
37+
current = current.next
38+
39+
return False
40+
41+
# Solution 2: 두 개의 포인터 이용
42+
class Solution:
43+
def hasCycle(self, head: Optional[ListNode]) -> bool:
44+
if not head:
45+
return False
46+
47+
slow = head
48+
fast = head
49+
50+
while fast and fast.next:
51+
slow = slow.next
52+
fast = fast.next.next
53+
54+
if slow == fast:
55+
return True
56+
57+
return False
58+
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
Constraints:
3+
- 1 <= nums.length <= 2 * 10^4
4+
- -10 <= nums[i] <= 10
5+
- The product of any subarray of nums is guaranteed to fit in a 32-bit integer.
6+
7+
Time Complexity:
8+
- O(n): 배열을 한 번만 순회하면서 각 위치에서 상수 시간 연산만 수행
9+
10+
Space Complexity:
11+
- O(1): 고정된 추가 변수만 사용 (curr_max, curr_min, ...)
12+
13+
풀이방법:
14+
1. DP로 각 위치에서 가능한 최대곱과 최소곱을 동시에 추적함
15+
2. 각 위치에서 세 개의 선택지 존재: 새로 시작 vs 이전 최대곱과 곱하기 vs 이전 최소곱과 곱하기
16+
3. 최소곱이 필요한 이유: 나중에 음수를 만났을 때 최대값이 될 수 있기 때문
17+
4. 매 단계마다 result 업데이트
18+
19+
고려사항:
20+
1. 값이 0인 경우 → 새로 시작해야 함
21+
2. temp 변수: curr_max를 업데이트하면 curr_min 계산 시 원래 값이 필요함
22+
"""
23+
class Solution:
24+
def maxProduct(self, nums: List[int]) -> int:
25+
curr_max = nums[0]
26+
curr_min = nums[0]
27+
result = nums[0]
28+
29+
for i in range(1, len(nums)):
30+
temp = curr_max
31+
curr_max = max(nums[i], curr_max * nums[i], curr_min * nums[i])
32+
curr_min = min(nums[i], temp * nums[i], curr_min * nums[i])
33+
result = max(result, curr_max)
34+
35+
return result
36+
37+
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
Constraints:
3+
- m == s.length
4+
- n == t.length
5+
- 1 <= m, n <= 10^5
6+
- s and t consist of uppercase and lowercase English letters.
7+
8+
Time Complexity: O(s * t)
9+
- for 루프로 s의 길이만큼 반복
10+
- while 루프 안의 all() 조건에서 t의 각 문자 비교
11+
- 따라서 O(s * t)
12+
13+
Space Complexity: O(s + t)
14+
- t_counts: O(t)의 공간
15+
- w_counts: O(s)의 공간
16+
- 따라서 O(s + t)
17+
18+
풀이방법:
19+
1. Counter로 t의 문자 빈도수 저장
20+
2. 슬라이딩 윈도우로 s 탐색:
21+
- high 포인터로 윈도우를 확장하며 필요한 문자 찾기
22+
- 필요한 문자를 모두 찾으면 low 포인터로 윈도우 축소
23+
3. 최소 길이의 윈도우 반환
24+
25+
메모:
26+
- 풀이 방법을 보고 익힘
27+
- 해시맵과 슬라이딩 윈도우 관련 다른 문제들을 풀고 이 문제 스스로 풀어보기
28+
"""
29+
class Solution:
30+
def minWindow(self, s: str, t: str) -> str:
31+
32+
t_counts = Counter(t)
33+
w_counts = Counter()
34+
35+
min_low, min_high = 0, len(s)
36+
low = 0
37+
38+
for high in range(len(s)):
39+
w_counts[s[high]] += 1
40+
41+
while all(t_counts[ch] <= w_counts[ch] for ch in t_counts):
42+
if high - low < min_high - min_low:
43+
min_low, min_high = low, high
44+
if s[low] in t_counts:
45+
w_counts[s[low]] -= 1
46+
low += 1
47+
48+
return s[min_low : min_high + 1] if min_high < len(s) else ""
49+
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""
2+
Constraints:
3+
- m == heights.length
4+
- n == heights[r].length
5+
- 1 <= m, n <= 200
6+
- 0 <= heights[r][c] <= 10^5
7+
8+
Time Complexity: O(m*n)
9+
- 각 셀을 최대 한 번씩만 방문함
10+
11+
Space Complexity: O(m*n)
12+
- visited sets(pacific, atlantic)가 최대 m*n 크기
13+
- 재귀 호출 스택도 최대 m*n 깊이 가능
14+
15+
풀이방법:
16+
1. Pacific(좌측상단)과 Atlantic(우측하단)의 경계에서 시작함
17+
2. DFS로 현재 높이보다 높거나 같은 인접 셀로만 이동함 (물은 위 -> 아래로 흐르지만, 거꾸로 접근했으니까)
18+
3. 각 바다에서 도달 가능한 셀들을 Set에 저장
19+
4. 두 Set의 교집합이 정답 (양쪽 바다로 모두 흐를 수 있는 지점들)
20+
"""
21+
class Solution:
22+
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
23+
if not heights:
24+
return []
25+
26+
rows, cols = len(heights), len(heights[0])
27+
pacific = set()
28+
atlantic = set()
29+
30+
def dfs(r, c, visited):
31+
visited.add((r, c))
32+
directions = [(1,0), (-1,0), (0,1), (0,-1)]
33+
34+
for dr, dc in directions:
35+
new_r, new_c = r + dr, c + dc
36+
if (new_r < 0 or new_r >= rows or
37+
new_c < 0 or new_c >= cols or
38+
(new_r, new_c) in visited):
39+
continue
40+
if heights[new_r][new_c] >= heights[r][c]:
41+
dfs(new_r, new_c, visited)
42+
43+
for c in range(cols):
44+
dfs(0, c, pacific)
45+
for r in range(rows):
46+
dfs(r, 0, pacific)
47+
48+
for c in range(cols):
49+
dfs(rows-1, c, atlantic)
50+
for r in range(rows):
51+
dfs(r, cols-1, atlantic)
52+
53+
return list(pacific & atlantic)

0 commit comments

Comments
 (0)