Skip to content

[KwonNayeon] Week 2 solutions #1207

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
Apr 11, 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
29 changes: 25 additions & 4 deletions 3sum/KwonNayeon.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,35 @@
1. 3 <= nums.length <= 3000
2. -10^5 <= nums[i] <= 10^5

Time Complexity:
- O(n^2) (정렬은 O(n log n), 이중 반복문은 O(n^2))
Space Complexity:
- O(n) (결과 리스트)
Time Complexity: O(n^2)
- 정렬은 O(n log n), 이중 반복문은 O(n^2)
Space Complexity: O(n)
- 결과 리스트를 저장하는 데 필요한 공간

풀이 방법:
- 투 포인터를 활용하여 합이 0이 되는 세 수 조합 찾기
- 배열 정렬: 투 포인터 사용 + 중복 처리 용이
- for 루프: 첫 번째 숫자 선택 (len(nums)-2까지)
- 중복된 첫 번째 숫자 건너뛰기
- left, right 포인터 설정
- while 루프: 두 포인터가 교차하지 않아야 함
- sum = nums[i] + nums[left] + nums[right] 계산
- sum == 0: 결과 추가, 중복 건너뛰기, 양쪽 포인터 이동
- sum < 0: left 증가 (더 큰 값 필요)
- sum > 0: right 감소 (더 작은 값 필요)
- 최종 결과 반환
"""
# Brute-force: three nested loops → O(n^3)
# Optimized: sort + two pointer → O(n^2)

class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# Step 1: Sort the array
# Step 2: Fix one number using for loop
# Step 3: Use two pointers to find two other numbers
# - if sum == 0: valid triplet
# - if sum < 0: move left pointer
# - if sum > 0: move right pointer
nums.sort()
result = []

Expand Down
36 changes: 22 additions & 14 deletions product-of-array-except-self/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
"""
Constraints:
1. 2 <= nums.length <= 10^5
2. -30 <= nums[i] <= 30
3. The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer
- 나눗셈 연산 사용 불가능
- O(n) 시간 복잡도로 구현해야 함
- 모든 prefix/suffix 곱은 32비트 정수 범위 내에 있음

Time Complexity: O(n)
- 배열을 두 번 순회하므로 O(n)
- 배열을 두 번만 순회

Space Complexity: O(1)
- 출력 배열(answer)을 제외하면 추가 공간이 상수만큼만 필요(left, right 변수)
- 출력 배열 추가 공간은 상수만 사용 (left, right 변수)

풀이 방법:
1. answer 배열을 1로 초기화 (곱셈에서는 1이 영향을 주지 않음)
2. 왼쪽에서 오른쪽으로 순회:
- answer[i]에 현재까지의 left 누적값을 곱함
- left *= nums[i]로 다음을 위해 left 값을 업데이트
3. 오른쪽에서 왼쪽으로 순회 (range(n-1, -1, -1) 사용):
- answer[i]에 현재까지의 right 누적값을 곱함
- right *= nums[i]로 다음을 위해 right 값을 업데이트
- 각 위치의 결과는 (왼쪽 모든 요소의 곱) * (오른쪽 모든 요소의 곱)
- 두 번의 순회로 이를 계산:
1. 왼쪽 -> 오른쪽: 각 위치에 왼쪽 모든 요소의 누적 곱 저장
2. 오른쪽 -> 왼쪽: 각 위치에 오른쪽 모든 요소의 누적 곱을 곱함

예시: nums = [1, 2, 3, 4]
1단계 후: answer = [1, 1, 2, 6]
2단계 후: answer = [24, 12, 8, 6]
"""

# Final result = (product of all elements on the left side) * (product of all elements on the right side)

# Step 1: Initialize result array with 1s
# Step 2: Traverse from left to right, storing cumulative product of left side
# Step 3: Traverse from right to left, multiplying with cumulative product of right side
# nums = [1,2,3,4]
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
Expand All @@ -29,10 +36,11 @@ def productExceptSelf(self, nums: List[int]) -> List[int]:
for i in range(n):
answer[i] *= left
left *= nums[i]

# answer = [1, 1, 2, 6] at this point
right = 1
for i in range(n-1, -1, -1):
answer[i] *= right
right *= nums[i]

return answer
# answer = [24,12,8,6]
24 changes: 10 additions & 14 deletions top-k-frequent-elements/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
"""
Title: 237. Top K Frequent Elements
Link: https://leetcode.com/problems/top-k-frequent-elements/

Question:
- Given an integer array `nums` and an integer `k`, return the `k` most frequent elements.
- You may return the answer in any order.
Problem: 237. Top K Frequent Elements

Constraints:
- 1 <= nums.length <= 10^5
- -10^4 <= nums[i] <= 10^4
- k is in the range [1, the number of unique elements in the array].
- The answer is guaranteed to be unique.
- 1 <= nums.length <= 10^5
- -10^4 <= nums[i] <= 10^4
- k is in the range [1, the number of unique elements in the array].
- The answer is guaranteed to be unique.

Time Complexity: O(n log n)
-

Time Complexity:
- O(n log n)
Space Complexity:
- O(n)
Space Complexity: O(n)
-
"""

# Original Solution
Expand Down
37 changes: 36 additions & 1 deletion validate-binary-search-tree/KwonNayeon.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
- The number of nodes in the tree is in the range [1, 10^4].
- -2^31 <= Node.val <= 2^31 - 1

<Solution 1: 재귀>
Time Complexity: O(n)
- 트리의 모든 노드를 한 번씩 방문함

Space Complexity: O(h)
- 재귀 호출 스택의 최대 깊이는 트리의 높이
- 스택에는 최대 h개의 노드가 저장됨 (h는 트리의 높이)

풀이방법:
1. 각 노드가 가질 수 있는 값의 범위를 한정함
Expand Down Expand Up @@ -40,3 +41,37 @@ def validate(node, min_val, max_val):

Copy link
Contributor

Choose a reason for hiding this comment

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

left 트리와 right 트리의 결과를 and 해서 return 하는 코드 깔끔하네요
저는 각각 비교했는데 더 짧고 간결해져서 좋네요

return validate(root, float("-inf"), float("inf"))

"""
<Solution 2: 반복문>
Time Complexity: O(n)
- 트리의 모든 노드를 한 번씩 방문함

Space Complexity: O(h)
- 스택에는 최대 h개의 노드가 저장됨 (h는 트리의 높이)

노트:
- 재귀와 동일한 순서로 노드를 방문함 (왼쪽 서브트리 → 현재 노드 → 오른쪽 서브트리)
- 트리가 매우 깊어질 경우 발생할 수 있는 스택 오버플로우를 방지할 수 있음
"""
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
stack = []
pre_val = float('-inf')
current = root

while current or stack:

while current:
stack.append(current)
current = current.left

current = stack.pop()

if current.val <= pre_val:
return False

pre_val = current.val
current = current.right

return True