Skip to content
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
28 changes: 28 additions & 0 deletions contains-duplicate/hi-rachel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
https://leetcode.com/problems/contains-duplicate/
Given an integer array nums,
return true if any value appears at least twice in the array,
and return false if every element is distinct.
TC: O(n)
SC: O(n)
"""

Copy link
Contributor

Choose a reason for hiding this comment

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

16줄의 seen = set() 방식은 하나씩 돌면서 바로 중복을 체크하는 방식이고,
28줄의 len(set(nums)) != len(nums) 방식은 전체 리스트를 한 번에 변환해 길이로 비교하는 방식입니다.
두 가지 방법을 함께 볼 수 있어서 이해하는 데 많은 분들에게 큰 도움이 될 것 같습니다!

from typing import List

class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
seen = set()

for num in nums:
if num in seen:
return True
else:
seen.add(num)
Comment on lines +21 to +22
Copy link
Member

Choose a reason for hiding this comment

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

바로 True를 리턴해주니까, else:는 없어도 될 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hyunjung-choi
num을 set에 넣지 않으면 seen 체크를 할 수가 없는데 (숫자를 이미 봤음)
혹시 더 설명해주실 수 있나요?

Copy link
Member

@hyunjung-choi hyunjung-choi Jul 24, 2025

Choose a reason for hiding this comment

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

@hi-rachel 아 저 뜻은 else:없이 바로

for num in nums:
    if num in seen:
        return True
    seen.add(num)
return False

이렇게 해도 될 것 같다는 뜻이었습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hyunjung-choi 굳이 else를 쓰지 않아도 된다는 말씀이셨군요. 그렇네요. 감사합니다!

return False


class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
return len(set(nums)) != len(nums)
26 changes: 22 additions & 4 deletions house-robber/hi-rachel.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,38 @@
# **dp[i] = max(dp[i-1], dp[i-2] + nums[i])**
# nums 길이가 2인 경우 range(2, 2)는 for문 안 돈다.

from typing import List

class Solution:
def rob(self, nums: List[int]) -> int:
if not nums: return 0
if len(nums) == 1: return nums[0]

if len(nums) == 1:
return nums[0]
dp = [0] * len(nums)
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])

for i in range(2, len(nums)):
dp[i] = max(dp[i - 1], nums[i] + dp[i - 2])
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])

return dp[-1]

"""
공간 최적화 풀이

prev2: i-2까지의 최대값 + 현재 돈
prev1: i번째 집 안 털고, 이전까지의 최대값 유지

TC: O(n)
SC: O(1)
"""
class Solution:
def rob(self, nums: List[int]) -> int:
prev2, prev1 = 0, 0
for num in nums:
prev2, prev1 = prev1, max(prev1, prev2 + num)
return prev1


# TS 코드
# function rob(nums: number[]): number {
Expand Down
42 changes: 37 additions & 5 deletions longest-consecutive-sequence/hi-rachel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# 처음 풀이
# O(n log n) time, O(n) space

from typing import List

class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
if nums == []:
Expand Down Expand Up @@ -67,11 +69,19 @@ def longestConsecutive(self, nums: List[int]) -> int:
return longest


# 최종 개선 풀이
# O(n) time, O(n) space
# 위 풀이에서 한쪽으로 구간을 찾지 않고, 양쪽으로 찾으며 숫자를 집합에서 제거하며
# 집합에서 원소가 하나도 남지 않을 때까지 하면 가장 긴 구간의 길이를 구할 수 있다.
# 배열의 모든 정수를 set에 저장했으므로 공간 복잡도는 O(n)
"""
최종 개선 풀이
O(n) time, O(n) space

위 풀이에서 한쪽으로 구간을 찾지 않고, 양쪽으로 찾으며 숫자를 집합에서 제거하며
집합에서 원소가 하나도 남지 않을 때까지 하면 가장 긴 구간의 길이를 구할 수 있다.

배열의 모든 정수를 set에 저장했으므로 공간 복잡도는 O(n), 시간 복잡도 O(n)
set 삽입: O(1), 삭제: 평균 O(1), 순서 보장 x => 순서를 무시하고 존재 여부(빠른 탐색)이 중요할 때 사용.
존재하지 않는 값을 pop(), remove()시 KeyError 주의

max(a, b): 두 값 중 큰 값을 반환 → O(1)
"""

class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
Expand All @@ -93,6 +103,28 @@ def longestConsecutive(self, nums: List[int]) -> int:

return longest

"""
25/7/23 복습, 위 최적화 풀이로 풀지 못함
TC: O(n log n)
SC: O(n)
"""
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
if not nums:
return 0
nums = sorted(list(set(nums)))
max_cnt = 1
cnt = 1

for i in range(len(nums) - 1):
if nums[i] + 1 == nums[i + 1]:
cnt += 1
max_cnt = max(max_cnt, cnt)
else:
cnt = 1

return max_cnt

# TS 풀이
# O(n) time, O(n) space
# JavaScript Set에서 값을 꺼내고자 할때는 **numSet.values().next().value** 사용
Expand Down
25 changes: 22 additions & 3 deletions top-k-frequent-elements/hi-rachel.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
# 가장 자주 등장한 상위 K개의 문자 배열 반환
# O(n log n) time, O(n) space
"""
https://leetcode.com/problems/top-k-frequent-elements/

Given an integer array nums and an integer k, return the k most frequent elements.
You may return the answer in any order.

TC: O(n log n)
SC: O(n)
"""

from collections import defaultdict
from typing import List

class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
numdict = defaultdict(int);
numdict = defaultdict(int)

for num in nums:
numdict[num] += 1
Expand All @@ -15,3 +23,14 @@ def topKFrequent(self, nums: List[int], k: int) -> List[int]:
keys = list(sort_dict)

return keys[:k]

# heapq 풀이
from collections import Counter
import heapq

class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
counter = Counter(nums)
return heapq.nlargest(k, counter.keys(), key=counter.get)


40 changes: 25 additions & 15 deletions two-sum/hi-rachel.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
"""
처음 풀이
O(N^2) time, O(N) space
"""
https://leetcode.com/problems/two-sum/

# class Solution:
# def twoSum(self, nums: List[int], target: int) -> List[int]:
# result = []
# for i in range(len(nums)):
# rest = target - nums[i]
# rest_nums = nums[i+1:]
# if rest in rest_nums:
# result.extend([i, rest_nums.index(rest)+i+1])
# break
# return result

Given an array of integers nums and an integer target,
return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.

"""
개선 코드
O(N) time, O(N) space
"""

from typing import List

class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
indices = {}
Expand All @@ -31,6 +23,24 @@ def twoSum(self, nums: List[int], target: int) -> List[int]:
return [i, j]
Copy link
Member

Choose a reason for hiding this comment

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

O(N)으로 개선하셨네요! 저도 개선해봐야겠어요!👍
근데 이렇게 하면 [1, 0]로 나오지 않나요??? 작은 인덱스가 먼저 나와야 할 것 같습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hyunjung-choi @printjin-gmailcom

https://leetcode.com/problems/two-sum/description/

문제에 'You can return the answer in any order.'라고 써있어서 그렇게 냈습니다!

리트코드 풀 때 반환을 요구하는 경우도 봤습니다. 그렇다면 [j, i]로 내야겠네요.

리뷰 감사합니다.

Copy link
Contributor

Choose a reason for hiding this comment

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

리턴할 때 [i, j] 대신 [j, i] 순서가 문제에서 요구하는 경우가 많으니, 문제 조건에 맞게 순서를 한 번 확인해보는 게 좋습니다.
(일반적으로 리트코드에선 이전 인덱스가 먼저 오기에 문제가 안 났지 않을까 싶습니다.)

indices[v] = i


"""
처음 풀이
O(N^2) time, O(N) space
"""

# class Solution:
# def twoSum(self, nums: List[int], target: int) -> List[int]:
# result = []
# for i in range(len(nums)):
# rest = target - nums[i]
# rest_nums = nums[i+1:]
# if rest in rest_nums:
# result.extend([i, rest_nums.index(rest)+i+1])
# break
# return result


# JS 풀이
# /**
# * @param {number[]} nums
Expand Down