Search in Rotated Sorted Array

초보개발·2023년 9월 3일
0

leetcode

목록 보기
23/39

문제

There is an integer array nums sorted in ascending order (with distinct values).

Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]. For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].

Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

You must write an algorithm with O(log n) runtime complexity.

풀이

  • O(logn) 풀이로 해결할 것
  • 회전된 배열의 피봇 k 찾기: 다음 값이 더 작을 때 피봇 k
  • 이진탐색을 위해 회전된 배열을 원상복구
  • target이 들어갈 위치를 bisect_left와 bisect_right로 비교하여 찾음
    • left의 결과 + 1이 right의 결과와 같다면 실제 인덱스 리턴
    • 존재하지 않으므로 -1

수도코드

for nums의 처음부터 끝의 -1까지:
	if 다음 숫자가 더 작은 경우:
    	pivot_k = i + 1
        break

원상복구된 배열 = nums[pivot_k: len(nums)] + nums[: pviot_k]

삽입 위치 = bisect_left
삽입 위치2 = biset_right

if 삽입 위치 + 1 == 삽입 위치2:
	return (pivot_k + 삽입위치) % len(nums)
return -1

Solution(Runtime: 47ms)

from bisect import bisect_left, bisect_right

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        k = 0
        for i in range(len(nums) - 1):
            if nums[i] > nums[i + 1]:
                k = i + 1
                break
        
        new_array = nums[k:len(nums)] + nums[:k]

        start_index = bisect_left(new_array, target)
        end_index = bisect_right(new_array, target)
 
        return (k + start_index) % len(nums) if start_index + 1 == end_index else -1

나는 회전축을 찾고 원래의 배열 상태로 되돌리고 나서 target을 찾도록 구현했다. 다른 사람의 풀이들은 원래의 배열상태로 되돌리지 않고 이진탐색으로 구현했다.

# 왼쪽 확인
if nums[start] <= nums[mid]:
	if nums[left] <= target < nums[mid]:
    	end = mid - 1
    else:
    	start = mid + 1
else:  # 오른쪽 확인
    if nums[mid] < target <= nums[end]:
        start = mid + 1
    else:
        end = mid - 1

0개의 댓글