查找有序数组中某个数首次出现的位置

给定一个排序的数组,找出数组中某个元素第一次出现的位置。如果没有找到返回-1.

某次面试时遇到这个题。当时用循环形式的二分查找做的,解决得一般。面试官提示用递归形式的二分查找,没能做出来。

重新思考了下这个问题,发现find2这种递归形式的,的确清晰一些。

但实际上循环形式的二分查找,只需使用一个数组mids,记录每次的mid值,最后返回mids数组末尾元素也可以解决问题。

def find2(arr, low, high, n):
    if low > high:
        return -1
    
    mid = low + (high - low) / 2
    if arr[mid] == n:
        index = find2(arr, low, mid - 1, n)
        return mid if index == -1 else index
    else:
        if arr[mid] > n:
            return find2(arr, low, mid - 1, n)
        else:
            return find2(arr, mid + 1, high, n)

 
def find(arr, n):
    low = 0
    high = len(arr) - 1
    
    mids = []
    while low <= high:
        #print low, high
        mid = (low + high) / 2
        if n < arr[mid]:
            high = mid - 1
        elif n > arr[mid]:
            low = mid + 1
        else:
            #return mid
            mids.append(mid)
            high = mid - 1
    
    if len(mids) == 0:
        return -1
    else:
        return mids[len(mids) - 1]

    
if __name__ == '__main__':
    arr = [1, 1, 2, 2, 3, 5, 6, 9, 10, 10, 10, 10, 12, 12, 23, 24, 25]
    print find(arr, 1)
    print find(arr, 2)
    print find(arr, 10)
    print find(arr, 12)
    
    print find2(arr, 0, len(arr), 1)
    print find2(arr, 0, len(arr), 2)
    print find2(arr, 0, len(arr), 10)
    print find2(arr, 0, len(arr), 12)

转载于:https://my.oschina.net/apm/blog/183784

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值