알고리즘 & 자료구조 >
이진탐색(LeetCode > 35. Search Insert Position)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
'''
1. 숫자들이 오름차순으로 정렬된 리스트와 타겟 넘버가 주어질 때, 리스트에서 타겟 넘버가 삽입될
인덱스를 구하는 문제.
2. 이진탐색을 구현할 때 주목해야 할 부분들
1) m = (s+e)//2
- 범위 내 수의 개수가 짝수 -> s에서 m까지의 개수와 m+1부터 e까지의 개수가 같다.
- 범위 내 수의 개수가 홀수 -> s에서 m까지의 개수가 m+1부터 e까지의 개수보다 하나 많다.
2) while s < e:
- 루프는 s==e가 된 상태에서 종료된다.
3) if nums[m] < target: s=m+1
- 이진탐색에서 제일 중요한 조건식 쓰기. 여기서 생각해야 할 게, 여기서 써야 하는 조건식은 결국
'target이 s ~ m 구간에 속하는 수인가? m+1 ~ e 구간에 속하는 수인가?'를 묻는 조건식이고,
nums[m]이라는 값을 사용해서 조건식을 쓰고자 한다면 결국 써야 하는 조건식은
'if nums[m] >= target' 또는 'if nums[m] < target'임.
여기서 써야하는 조건식의 의미에 대한 이해가 부족하면, nums[m]==target인 경우를 어떻게 처리해야 할지
판단이 어려워져서 코드가 조금 길어지고 복잡한 예외처리를 해야 하는 경우가 생길 수 있음.
(길어져봐야 서너 줄 정도에 불과하긴 하나 그 서너 줄 없이 정확히 작동하는 코드를 쓸 수 있다는 점.)
특히 문제가 만약 이 문제처럼 '타겟 넘버가 리스트에 없다면 타겟 넘버가 삽입돼야 할 위치를 리턴하라'
는 문제라면, '타겟 넘버가 s ~ m 영역보다 큰 수라면 다음 루프는 m+1 ~ e 영역을 탐색'이라는 식으로
코드를 쓰면 '루프가 끝나는 지점(s==e)이 곧 타겟 넘버가 삽입돼야 할 지점'이라는 내용이 간단히 구현됨.
이 부분을 파악 못하면 코드가 이것보다 다소 길어질 것.
'''
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
s, e = 0, len(nums)-1
while s < e:
m = (s+e)//2
if nums[m] < target:
s = m+1
else:
e = m
return e + ( 1 if target > nums[e] else 0)
알고리즘 & 자료구조 카테고리의 다른 글