旋转数组查找

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

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

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
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)

 

这段代码非常关键:

1
2
3
4
5
6
7
8
9
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)

 

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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))

 

posted @   bonelee  阅读(526)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2017-01-06 NoSQL生态系统——一致性RWN协议,向量时钟,gossip协议监测故障
2017-01-06 NoSQL生态系统——hash分片和范围分片两种分片
2017-01-06 NoSQL生态系统——事务机制,行锁,LSM,缓存多次写操作,RWN
2017-01-06 NoSQL生态系统——类似Bigtable列存储,或者Dynamo的key存储(kv存储如BDB,结构化存储如redis,文档存储如mongoDB)
2017-01-06 ubuntu 下非交互式执行远程shell命令
2017-01-06 Dynamo分布式系统——「RWN」协议解决多备份数据如何读写来保证数据一致性,而「向量时钟」来保证当读取到多个备份数据的时候,如何判断哪些数据是最新的这种情况
点击右上角即可分享
微信分享提示