바위타는 두루미

10.3 회전된 배열에서 검색 본문

Study/Interview준비

10.3 회전된 배열에서 검색

DoRoMii 2019. 8. 6. 12:35
728x90

문제

n개의 정수로 구성된 정렬 상태의 배열을 임의의 횟수만큼 회전시켜 얻은 배열이 입력으로 주어진다고 하자. 이 배열에서 특정한 원소를 찾는 코드를 작성하라. 회전 시키기 전, 원래 배열은 오름차순으로 정렬되어 있었다고 가정한다. 

 

입력 : {15,15,19,20,25,1,3,4,5,7,10,14} , 5

출력  : 8 ( 배열에서 8번째 인덱스에 5가 있으므로)

 

접근법

이 문제를 보고 이진탐색을 생각했다면 매우 훌륭하다.

고전적인 이진탐색은 어떤 값 x가 왼쪽에 있는지 오른쪽에 있는지를 판단하기 위해  x를 배열의 중간 원소와 비교한다.

하지만, 이 문제는 배열이 회전된 상태라서 까다롭다. 두 배열을보자

배열 1 {10,15,20,0,5}

배열 2 {50,5,20,30,40}

이 두배열 모두 20이 가운데에 있지만, 5는 왼쪽에 있을수도 오른쪽에 있을 수도 있다.

하지만 좀더 자세히 들여다 보면, 왼쪽 또는 오른쪽은 제대로 정렬이 되어있음을 알 수 있다.

배열 1에서는 mid는 20이고 left = 10 , right =5이다. 그러면 left < mid 이므로 왼쪽은 재대로 정렬되어있음을 알 수 있다. 

하지만 왼쪽 범위안에 5가 들어갈 수 업으므로 오른쪽을 탐색해야 할 것이다.

배열 2에서는 mid는 20이고 left= 50 , right=40으로 mid < right으로 오른쪽은 제대로 정렬되어있음을 알 수 있다.

하지만 오른쪽 범위안에 5가 들어갈 수 없으므로 왼쪽을 탐색해야 할 것이다.

 

그럼 이런 경우는 어떨까?

배열 3 {2,2,2,3,5,2}

중복된 원소가 있을때는 더 까다로울 것이다. 이렇게 가운데 원소와 왼쪽 끝의 원소가 같은 경우는 어떻게 해야할까?

맨 오른쪽 원소가 같은지 확인하고 오른쪽 원소가 다르다면 오른쪽을 탐색하면 될 것이다. 

이렇게 오른쪽도 같다면 양쪽을 모두 확인해 보아야 한다. 

왼쪽을 탐색하고 답이 없다면 오른쪽도 탐색하는 방향으로 설계해야 할 것이다.

 

def Solution(nums, target):
    return serach(nums,0, len(nums)-1, target)

def serach(nums, left, right, target) :
    mid = (left+right) / 2
    if nums[mid] == target :
        return mid
    if left > right :
        return -1

    if  nums[left] < nums[mid] : # 왼쪽이 정렬된 경우
        if nums[left] <=  target and  target < nums[mid]:
            return serach(nums, left, mid-1, target)
        else :
            return serach(nums, mid+1 , right, target)
    elif nums[mid] < nums[right] :
        if nums[mid] < target and target <= nums[right]:
            return serach(nums, mid+1, right, target)
        else :
            return serach(nums, left, mid-1, target)
    elif nums[left] == nums[mid]:
        if nums[right] != nums[mid]:
            return serach(nums, mid+1, right, target)
        else :
            result = serach(nums, left, mid-1, target)
            if result == -1 :
                return serach(nums, mid+1, right, target)
            else :
                return result
    else :
        return -1

'Study > Interview준비' 카테고리의 다른 글

10.5 드문드문 탐색  (0) 2019.08.06
10.4 크기를 모르는 정렬된 원소 탐색  (0) 2019.08.06
10.2 Anagram 묶기  (0) 2019.08.06
8.14 불린 값 계산  (0) 2019.08.05
8.13 박스 쌓기  (0) 2019.08.05
Comments