-
-
Notifications
You must be signed in to change notification settings - Fork 246
[rara-record] WEEK 01 solutions #1699
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from typing import List | ||
|
||
""" | ||
문제 설명: | ||
- 배열에 중복된 값이 하나라도 있으면 True, 아니면 False를 반환하는 문제 | ||
|
||
목표 | ||
- 배열을 순회하면서 각 값을 set에 추가 | ||
- set은 중복을 허용하지 않으므로, 이미 set에 값이 있으면 중복이 발생한 것 | ||
- 중복이 발견되면 true, 없으면 false 반환 | ||
|
||
시간복잡도: O(n) | ||
- 배열을 한 번만 순회하므로 O(n) | ||
|
||
공간복잡도: O(n) | ||
- set에 n개의 값이 저장됨 | ||
""" | ||
|
||
class Solution: | ||
def containsDuplicate(self, nums: List[int]) -> bool: | ||
num_set = set() | ||
for num in nums: | ||
if num in num_set: | ||
return True | ||
else: | ||
num_set.add(num) | ||
return False | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
from typing import List | ||
|
||
""" | ||
문제 설명: | ||
정렬되지 않은 정수 배열에서 가장 긴 연속된 숫자 수열의 길이를 반환하는 문제 | ||
O(n) 시간복잡도로 해결해야 함 => 정렬 x | ||
|
||
목표: | ||
- 해시 세트로 중복 제거 | ||
- 연속 수열의 시작점 찾기 | ||
|
||
[100,4,200,1,3,2] | ||
- 해시 세트: {100, 4, 200, 1, 3, 2} | ||
- 시작점 찾기: 1 (0이 없음), 100 (99가 없음), 200 (199가 없음) | ||
- 1에서 시작: 1→2→3→4 (길이 4) | ||
- 100에서 시작: 100만 (길이 1) | ||
- 200에서 시작: 200만 (길이 1) | ||
- 최대 길이: 4 | ||
|
||
- for num=1: 0이 없으므로 시작점 → while에서 1,2,3,4 처리 | ||
- for num=2: 1이 있으므로 while 스킵 | ||
- for num=3: 2가 있으므로 while 스킵 | ||
- for num=4: 3이 있으므로 while 스킵 | ||
→ 각 숫자가 while에서 1번만 | ||
""" | ||
|
||
""" | ||
시간복잡도: O(n) | ||
- set(nums) 변환: O(n) | ||
- 외부 for 루프: O(n)번 실행 | ||
- while 총 실행 횟수: 전체 알고리즘에서 각 숫자가 while 안에서 최대 1번만 처리됨 | ||
→ 총 while 내부 작업 = n번 → O(n) | ||
- 해시 조회: O(1) × 총 조회 횟수 | ||
- 전체: O(n) + O(n) + O(n) = O(n) | ||
|
||
공간복잡도: O(n) | ||
- num_set: 최대 n개의 서로 다른 숫자 저장 -> O(n) | ||
- 기타 변수들: O(1) | ||
- 전체: O(n) | ||
""" | ||
|
||
class Solution: | ||
def longestConsecutive(self, nums: List[int]) -> int: | ||
num_set = set(nums) | ||
max_length = 0 | ||
|
||
|
||
for num in num_set: | ||
|
||
# 루프 안에서 한번만 처리 | ||
if num - 1 not in num_set: | ||
current_length = 1 | ||
|
||
while num + current_length in num_set: | ||
current_length += 1 | ||
Comment on lines
+54
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 문제를 풀 때 저는 처음에는 이 while문을 보고 n^2가 아닌가 생각했지만 오직 1번만 실행되기에 2N -> N 인 것을 알았습니다. 수고하셨어요! |
||
|
||
max_length = max(max_length, current_length) | ||
|
||
|
||
return max_length | ||
|
||
print(Solution().longestConsecutive([100, 4, 200, 1, 3, 2])) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from typing import List | ||
from heapq import nlargest | ||
|
||
""" | ||
문제 설명: | ||
이 문제는 주어진 k번째 만큼 빈도수가 높은 값들을 반환하는 문제 | ||
빈도수 체크 후, 반환 값 순서는 상관 없다고 했으니 heap 사용 | ||
{ | ||
1: 3, # 1이 3번 등장 | ||
2: 2, # 2가 2번 등장 | ||
3: 1, # 3이 1번 등장 | ||
} | ||
빈도수 기준으로 k번째만큼 큰 값을 반환 | ||
""" | ||
|
||
class Solution: | ||
def topKFrequent(self, nums: List[int], k: int) -> List[int]: | ||
count_dic = {} | ||
|
||
for num in nums: | ||
if num in count_dic: | ||
count_dic[num] += 1 | ||
else: | ||
count_dic[num] = 1 | ||
|
||
# 빈도수가 큰 순서대로 k개를 반환 | ||
return nlargest(k, count_dic, key=count_dic.get) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nlargest() 라는 함수가 있군요 처음알았습니다! |
||
|
||
""" | ||
시간복잡도: O(n log k) | ||
- 딕셔너리 O(n) + heap을 사용해서 k번째 요소까지 반환 O(n log k) = O(n log k) | ||
공간복잡도: O(n) | ||
- 최대 n개의 서로 다른 숫자가 있을 수 있고, O(n) | ||
- heap은 최대 k개만 저장 -> O(k) | ||
전체적으로 O(n) | ||
""" | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from typing import List | ||
|
||
""" | ||
문제 설명: | ||
nums에서 두 수를 더해 target이 되는 두 인덱스를 찾아 반환하는 문제 | ||
같은 원소를 두 번 쓸 수 없음 | ||
찾야야하는 값: taget - 현재 숫자 = 더해서 target이 되는 값 | ||
|
||
nums = [2,7,11,15], target = 9 | ||
{ | ||
2: 0, (value: index) | ||
7: 1, | ||
11: 2, | ||
15: 3, | ||
} | ||
|
||
1. nums를 한 번 순회하며 각 숫자와 인덱스를 딕셔너리에 저장 | ||
2. 다시 nums를 순회하며, target - 현재 숫자가 딕셔너리에 있고 인덱스가 다르면 정답 쌍을 반환 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요 부분을 생각해내는게 포인트였던 것 같습니다. target이 되는 2개의 인덱스를 반환해야하므로, 딕셔너리를 사용해서 index정보를 넣고 key로 그 index를 뽑아내는 접근이 좋았습니다. |
||
""" | ||
|
||
|
||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
dic = {} | ||
|
||
for key, value in enumerate(nums): | ||
dic[value] = key | ||
|
||
# 다시 nums를 순회 | ||
for key, value in enumerate(nums): | ||
match = target - value | ||
|
||
# 같은 원소를 두번 쓸 수 없다. | ||
if (match in dic) and key != dic[match]: | ||
return [key, dic[match]] | ||
|
||
""" | ||
시간 복잡도: O(n) | ||
- 리스트를 두 번 순회하지만 각각 O(n)이 소요되므로, 총 시간 복잡도는 O(n) | ||
공간 복잡도: O(n) | ||
- 입력 크기가 n이라면 딕셔너리의 크기도 최대 n | ||
""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 단순히 set으로 nums를 넣고 길이비교를 생각했었는데 rara님 처럼 풀면 배열 수가 많아질경우 중복된 수가 앞쪽에 있다면 더 빨리 문제가 해결될 것 같습니다!
저희가 코드를 짤때도 실패되는 케이스나 성공하는 케이스에 대해 빠르게 return하는 것을 지향하는 것으로 알고있는데 (무슨 방법론이었나 ..? 이름이 생각이 안나네요..) 좋은 접근인 것 같습니다 ㅎㅎ