二分法查找-Python

一维数组查找

中心思想:
数列从小到大排序,定义查找的范围 [left,right],每次取中点的数值mid跟target比较,如果相等,则mid为查找目标,如果不等则根据nums[mid]和target的大小缩小查找范围
具体步骤:
1、设定左右指针
2、计算中间值mid,并判断nums[mid]与target的大小
3、如果nums[mid] < target,左指针右移left = mid + 1
4、如果nums[mid] > target,右指针左移right= mid - 1
5、重复2、3、4步骤直到nums[mid] = target或left > right

例1:判断target是否在nums中,若存在,返回下标值,若不存在,返回-1

nums = [-1,0,3,5,8,12]
target = 9
left = 0
right = len(nums)-1
res = -1
while left <= right:
    mid = (left+right) // 2
    num = nums[mid]
    if num == target:
        res = mid
        break
    elif num < target:
        left = mid + 1
    else:
        right = mid - 1
print(res)
>>> -1

例2:判断target是否在nums中,若存在,返回下标值,若不存在,返回它将会被按顺序插入的位置

nums = [3,5,7,9,10]
target = 8
left = 0
right = len(nums)-1
res = -1
while left <= right:
    mid = (left+right) // 2
    num = nums[mid]
    if num == target:
        res = mid
        break
    elif num < target:
        left = mid + 1
    else:
        right = mid -1
    if left > right:
        if num < target:
            res = mid + 1
        else:
            res = mid
print(res)

>>> 3

二维数组查找

中心思想:
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。利用数组的递增性从左下角开始查找,若比target大,则往右查找,若比target小,则往上查找。
具体步骤:
1、初始位置为左下角
2、如果array[m][n] < target,往右查找,n+=1
3、如果array[m][n] > target,往上查找,m-=1
4、重复2、3步骤直到m或n到达边界

array = [[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
target = 7
m = len(array) - 1
n = 0
res = 0
while n < len(array[0]) and m >= 0:
    if array[m][n] == target:
        res = 1
        break
    if array[m][n] > target:
        m -= 1
    if array[m][n] < target:
        n += 1
if res:
    print("true")
else:
    print("false")
    
>>> true

分治并归

中心思想:
分:将数组划分成最小为1个元素的子数组
并:从最小的数组按照顺序合并,从小到大依次向上合并,最后得到合并完的顺序数组
例:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。
在这里插入图片描述

data = [1,2,3,4,5,6,7,0]
def merge_sort(data):
    count = 0
    def merge(left,right):
        count = 0
        res = []
        i,j = 0,0
        while i < len(left) and j < len(right):
            if left[i] <= right[j]:
                res.append(left[i])
                i += 1
            else:
                res.append(right[j])
                j += 1
                count += (len(left)-i)
        res += left[i:] + right[j:]
        return count, res
    if len(data) <= 1:
        return 0, data
    else:
        mid = len(data) // 2
        num_left, left = merge_sort(data[:mid])
        num_right, right = merge_sort(data[mid:])
        num_merge, new_list = merge(left, right)
        count = num_left + num_right + num_merge
        return count, new_list
        
num, new_list = merge_sort(data)
print(num)

>>> 7
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值