제로베이스 백엔드 스쿨 김태원 님이 진행하신 알고리즘 특강 복습
자바로 진행했지만 코테는 파이썬으로 푸는 게 아직 익숙해서 파이썬으로 정리했다.
문제: 길이가 n인 배열 중 다른 값 두 개를 더했을 때, 주어진 target 과 값이 같다면 두 값을 출력하고,
없다면 [0, 0]을 출력. 단, 두 수를 합했을 때, target 이 되는 쌍은 하나만 존재.
1. 이중 for 문을 사용한 풀이 O(N^2)
|
1
2
3
4
5
6
7
|
def solution (arr, target):
for i in range(len(arr) -1):
for j in range(i , len(arr)):
if arr[i] + arr[j] == target:
return [arr[i], arr[j]]
return [0, 0]
|
cs |
가장 간단하게 모든 경우의 수를 모두 해보면서 중간에 target 과 합이 같은 쌍이 나오면 중지.
2. 투포인터 O(nlogn)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
def solution (arr, target):
arr.sort()
left = 0
right = len(arr) - 1;
while left < right :
if arr[left] + arr[right] == target:
return [arr[left], arr[right]]
elif arr[left] + arr[right] > target:
right -= 1
else:
left += 1
return [0, 0]
|
cs |
* 전제조건이 필요하다. 배열이 정렬 되어 있어야 한다. 정렬을 사용했기 때문에 시간 복잡도는 O(nlogn) 이다.
파이썬에서 sort() 함수는 팀 소트 방식을 사용한다. 이는 병합정렬과 삽입정렬을 혼합하여 만든 방식이다.
조금 더 깊이 공부하고 싶다면 아래 링크를 참조하면 좋을 것 같다.
https://d2.naver.com/helloworld/0315536
오름차순으로 정렬을 하면 왼쪽 포인터가 가르키는 것이 가장 작은 값 이고, 오른쪽 포인터가 가르키는 값은 가장 큰 값이다.
왼쪽 포인터가 오른쪽 포인터가 가르키는 값을 더했을 때, 타겟보다 합이 크면 값이 작아져야 한다.
오른쪽 포인터가 왼쪽으로 이동하면 값이 작아진다.
반대로 더한 값이 작을 때는 왼쪽 포인터가 오른쪽으로 옮겨주고, 값이 커진다.
왼쪽 포인터와 오른쪽 포인터가 같아 지거나, 오른쪽 인덱스 값이 왼쪽 인덱스 보다 작아질 때
해당 배열에서는 두 수의 합이 타켓을 충족하는 값이 없다. 따라서 반복문을 탈출한다.
3. set 사용해서 풀기 O(N)
|
1
2
3
4
5
6
7
8
9
10
|
def solution (arr, target):
candidate = set()
for i in arr:
if i in candidate:
return([i, target - i])
else:
candidate.add(target - i)
return [0, 0]
|
cs |
배열의 값을 한 번 돌면서 target 이 되려면 필요한 값 == target 에서 i 를 뺀 값 을 set 에 저장한다.
만약에 배열에 i 가 있다면 앞에서 i와 더했을 때 target 이 되는 값이 있다는 의미이므로
i 와 target - i 를 return 하고 반복문을 종료한다.
강의에서는 해시를 사용해서 푸는 방법이 있다고 하셨고, 구글링도 해시 테이블로 했지만
어차피 target 에서 i 를 빼면 되니까 굳이 딕셔너리 사용해서 i 값을 저장할 필요가 없다고 생각했다.
set이나, 딕셔너리나 둘다 해시 테이블 쓰는 거니까 자기 하고 싶은 거로 하면 될 것 같다.
'IT > Python' 카테고리의 다른 글
| [codility] Greedy MaxNonoverlappingSegments (0) | 2023.03.29 |
|---|---|
| [Greedy] (0) | 2023.03.29 |
| [프로그래머스] 파일명 정렬 (안정 정렬이란?) (0) | 2022.08.09 |
| 파이썬 리스트 선언시 주의 (0) | 2021.07.02 |
| 파이썬 소수판별 (에라토스테네스 체) (0) | 2021.07.01 |