Skip to content
Merged
12 changes: 12 additions & 0 deletions contains-duplicate/hu6r1s.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from collections import Counter

class Solution:
# 시간복잡도: O(n) - Counter(nums)는 n번 순회하며 각 원소의 개수를 세고, cnt.items()는 최대 n개의 (key, value) 쌍을 포함하므로 최대 n번 순회
# 공간복잡도: O(n) - Counter는 입력 배열에 있는 각 고유 원소를 키로 저장하므로 최악의 경우 n개의 키를 저장함
def containsDuplicate(self, nums: List[int]) -> bool:
cnt = Counter(nums)
for _, v in cnt.items():
if v >= 2:
return True
else:
return False
45 changes: 45 additions & 0 deletions house-robber/hu6r1s.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class Solution:
"""
- 이전 풀이
[1,2,3,1]
인덱스 0에서 훔쳤을 때, 인덱스 1은 훔치면 안되므로 nums[0] + F(nums[2:])
인덱스 0에서 안훔쳤을 때, 인덱스 1에서 훔쳐야 하므로 F(nums[1:])

F[nums] = max(nums[0] + F[nums[2:]], F(nums[1:]))
F[i] = max(nums[i] + F(i+2), F(i+1))


- dp
nums = [1, 2, 3, 1]
집이 하나일 때는 한 곳만 볼 수 있으니 그 집의 돈을 훔침: dp[0] = nums[0] = 1
집이 두 개일 때, 인덱스 0인 곳을 갔다면 dp[0]이 가장 크고,
가지 않았다면 인덱스 1을 가게 됨. dp[1] = max(dp[0], nums[1]) = max(1, 2) = 2
그래서 인덱스 0을 갔을 때와 가지 않았을 때를 고려하여 큰 돈을 가져옴
집이 세 개일 때, 인덱스 0을 갔다면 인덱스 2를 가야하고, 인덱스 0을 가지 않았다면 인덱스 1을 감
이를 고려하면, 인덱스 0을 갔을 때의 가장 큰 값이 dp[0]이고, 인덱스 2를 가야하니 nums[2]를 더한 값과
인덱스 0에 가지 않고 인덱스 1로 갔다면 dp[1]이 가장 크다.
그래서 dp[2] = max(dp[0] + nums[2], dp[1])
집이 네 개일 때, 인덱스 3을 간다면 인덱스 1을 가게 되므로 인덱스 1까지의 dp 값과 인덱스 3의 값을 더한 값과
인덱스 3을 가지 않는다면 인덱스 0과 인덱스 2를 가게 된다.
그렇다면 인덱스 2까지의 값을 비교하여 더 큰 돈을 가져간다.
그래서 dp[3] = max(dp[1] + nums[3], dp[2])가 된다.

- TC
- for loop -> O(n)
- SC
- dp 테이블 크기 -> O(n)
"""
def rob(self, nums: List[int]) -> int:
if not nums:
return 0
if len(nums) == 1:
return nums[0]

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

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

return dp[-1]
31 changes: 31 additions & 0 deletions longest-consecutive-sequence/hu6r1s.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class Solution:
"""
nums를 내림차순 sort하고, 차례대로 두 개의 차가 다음 차가 같다면 + 1
처음 차는 diff 변수에 저장하고, 진행되면서 diff를 업데이트
200, 100, 4, 3, 2, 1

연속된 수열이라고 하여 1 이외의 다른 수가 올 수 있을 것이라고 판단하였지만 차이가 1로 나온다는 것을 확인

- TC
- set(nums) -> O(n)
- for -> O(n)
- while -> O(n)
- 전체 -> O(n)
- SC
- num_set -> O(n)
- 다른 변수들 -> O(1)
- 전체 -> O(n)
"""
def longestConsecutive(self, nums: List[int]) -> int:
num_set = set(nums)
longest = 0

for num in num_set:
if num - 1 not in num_set:
k = 1

while num + k in num_set:
k += 1

longest = max(longest, k)
return longest
18 changes: 18 additions & 0 deletions top-k-frequent-elements/hu6r1s.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from collections import Counter

class Solution:
"""
- TC
- Counter(nums): O(n)
- sorted(): O(n log n)
- 슬라이싱 및 리스트 변환: O(k)
- 전체: O(n log n)
- SP
- Counter 및 정렬된 딕셔너리 저장: O(n)
- 반환 리스트: O(k)
- 전체: O(n)
"""
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
count_nums = Counter(nums)
count_nums = dict(sorted(count_nums.items(), reverse=True, key=lambda x: x[1])).keys()
return list(count_nums)[:k]
27 changes: 27 additions & 0 deletions two-sum/hu6r1s.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
- Time Complexity
- 바깥 for 루프는 n - 1번, 안쪽 루프는 최대 n - i - 1번 실행
- 전체적으로 O(n^2)의 시간 복잡도를 가짐짐

- Space Complexity
- 별도의 자료구조를 사용하지 않음
- 변수 i, j 그리고 리턴 시 사용하는 [i, j]만 존재
- 따라서 O(1)의 공간 복잡도를 가짐짐
"""
"""
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)-1):
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
return [i, j]
"""

class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
d = {num: idx for idx, num in enumerate(nums)}

for i, v in enumerate(nums):
idx = target - v
if idx in d and d[idx] != i:
return [i, d[idx]]