旋转数组查找

Posted bonelee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了旋转数组查找相关的知识,希望对你有一定的参考价值。

程序员面试金典里的解法才是正解,逻辑上没有漏洞,其他书籍的解法是有问题的:

无论数组是否有相同数字。都可以使用下面解法:

def search(arr, left, right, x):
    if left > right: return -1
    mid = (left+right)/2
    if x == mid:
        return mid
   
    # 你先看下最外围的三个if, 逻辑完备,>, <, = 都考虑到了!!!
    if arr[left] < arr[mid]:
        # 再看里面的if,都是在确定究竟哪一段有序
        if x>= arr[left] and x<arr[mid]:
            return search(arr, left, mid-1, x)
        else:
            return search(arr, mid+1, right, x)
    elif arr[mid] < arr[left]:
        if x>arr[mid] and x<=arr[right]:
             return search(arr, mid+1, right, x)
        else:
             return search(arr, left, mid-1, x)
     else:
         if arr[mid] == arr[right]: # 说明arr[mid]==arr[left]==arr[right],两边都有相等数据,只能两边继续二分
              result = search(arr, left, mid-1, x)
              if result == -1:
                  return search(arr, mid+1, right, x)
              else:
                  return result
         else: # 说明 arr[mid]!=arr[right],仅left这边遇到相等
             return search(arr, mid+1, right, x) 

 

这段代码非常关键:

 else:
         if arr[mid] == arr[right]: # 说明arr[mid]==arr[left]==arr[right],两边都有相等数据,只能两边继续二分
              result = search(arr, left, mid-1, x)
              if result == -1:
                  return search(arr, mid+1, right, x)
              else:
                  return result
         else: # 说明 arr[mid]!=arr[right],仅left这边遇到相等
             return search(arr, mid+1, right, x) 

 

 

同理,对于求解旋转数组最小值的解法:

def get_min_of_rotation(arr, left, right):
    assert left <= right
    if left == right: return arr[left]
    mid = (left+right)/2
    if arr[mid] > arr[left]:
        return min(arr[left], get_min_of_rotation(arr, mid+1, right))        
    elif arr[mid] < arr[left]:
        return min(arr[mid], get_min_of_rotation(arr, left, mid-1))            
    else:
        if arr[mid] != arr[right]:
            return min(arr[mid], get_min_of_rotation(arr, mid+1, right))  
        else:
            return min(arr[mid], get_min_of_rotation(arr, mid+1, right), get_min_of_rotation(arr, left, mid-1)) 

 

以上是关于旋转数组查找的主要内容,如果未能解决你的问题,请参考以下文章

旋转数组的最小数字

旋转数组中的元素查找

二分查找团灭力扣旋转排序数组系列

二分查找解决旋转数组

剑指offer java -查找旋转数组的最小数字

剑指 Offer 11. 旋转数组的最小数字暴力二分查找