# 최솟값을 찾기 left, right = 0, len(nums) - 1 while left < right: mid = left + (right - left) // 2
if nums[mid] > nums[right]: left = mid + 1 else: right = mid pivot = left
# 피벗 기준 이진 검색 left, right = 0, len(nums) while left <= right: mid = left + (right - left) // 2 mid_pivot = (mid + pivot) % len(nums)
if nums[mid_pivot] < target: left = mid + 1 elif nums[mid_pivot] > target: right = mid - 1 else: return mid_pivot
return -1
#67 두 배열의 교집합
두 배열의 교집합을 구하라
입력
1 2
num1 = [1, 2, 2, 1] num2 = [2, 2]
이진 검색으로 일치 여부 판별
1 2 3 4 5 6 7 8 9
defintersection(num1: list, num2: list) -> set: res = set() num2.sort() for n1 in num1: # 이진 검색으로 일치 여부 판별 i2 = bisect.bisect_left(num2, n1) iflen(num2) > 0andlen(num2) > i2 and n1 == num2[i2]: res.add(n1) return res
한쪽은 순서대로 탐색, 다른쪽은 정렬해서 이진 검색으로 값을 찾는다
num2 를 정렬한 상태에서 num1 을 순차 반복하면서 num2 를 이진 검색 한다
투 포인터로 일치 여부 판별
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
defintersectioin_two_pointer(num1: list, num2: list) -> set: res = set() num1.sort() num2.sort() i = j = 0 # 투 포인터 우측으로 이동하며 일치 여부 판별 while i < len(num1) and j < len(num2): if num1[i] > num2[j]: j += 1 elif num1[i] < num2[j]: i += 1 else: res.add(num1[i]) i += 1 j += 1 return res
각각의 입력받은 리스트를 정렬한다
값이 작은 쪽 배열 포인터가 한 칸씩 앞으로 이동하는 형태이고 어느 한쪽의 포인터가 끝까지 도달하면 종료하게된다
#68 두 수의 합
정렬된 배열을 받아 덧셈하여 타겟을 만들 수 있는 배열의 두 숫자 인덱스를 리턴하라 (배열의 시작은 1로 한다)
입력
1 2
numbers = [2, 7, 11, 15] target = 9
투 포인터
1 2 3 4 5 6 7 8 9
deftwoPointer(number: list, target: int) -> list: left, right = 0, len(number) - 1 whilenot left == right: if number[left] + number[right] < target: left += 1 elif number[left] + number[right] > target: right -= 1 else: return [left + 1, right + 1]
bisect 모듈
1 2 3 4 5 6 7
defbisect_slicing(number: list, target: int) -> list: for k, v inenumerate(number): expected = target - v nums = number[k + 1] i = bisect.bisect_left(nums, expected) if i < len(nums) and number[i + k + 1] == expected: return [k + 1, i + k + 2]
#69 2D 행렬 검색
mxn 행렬에서 값을 찾아내는 효율적인 알고리즘을 구현하라. 행렬은 왼쪽에서 오른쪽, 위에서 아래 오름차순으로 정렬되어 있다