#35搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

示例 1:

输入: [1,3,5,6], 5
输出: 2
示例 2:

输入: [1,3,5,6], 2
输出: 1
示例 3:

输入: [1,3,5,6], 7
输出: 4
示例 4:

输入: [1,3,5,6], 0
输出: 0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-insert-position
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

先想到用二分查找,递归实现,由于递归需要在传参时传入low和high,但函数原型里没有这2个参数,所以没写递归方式。查了下下面是迭代实现。

前提是升序且无重复元素,下面的代码有重复元素时可能返回的不是第一次出现的位置。
找不到时返回low的原因:
target小于整个原区间时,low一直为0不变,若最终未找到,则应插入到下标为0的位置,这个位置也是low的位置;
target大于整个原区间时,high一直为最后一个元素不变,若最终未找到,则应插入到最后一个元素的后面,此时循环因low>high而终止,即此时low在high后面,这时low的位置就是要插入的位置;
target属于某个中间区间时,若最终未找到,最后区间内剩2个元素。一种情况是low和mid和high相等,且target大于它们,则low的值变为mid+1,此时因low>high导致循环终止,因这时low的位置是target第一次大于某元素的位置,即要插入的位置,所以返回low;另一种情况是low和mid的值相同且mid>target,所以high的值变为mid-1,导致low>high,循环终止,因mid是第一个大于target的位置,且low和mid相等,所以这时low的位置就是要插入的位置。

def binary_search(nums,target):
    low=0
    high=len(nums)-1
    while low<=high:
        mid=(low+high)//2
        if target<nums[mid]:
            high=mid-1
        elif target>nums[mid]:
            low=mid+1
        elif target==nums[mid]:
            return mid
    return low
nums=[1,3,5,7,9]
for i in [0,1,2,8,9,10]:
    print(binary_search(nums,i))

题解中看到的一些知识:

1.链接中作者对评论的回复

因为计算机位数是有限的,假如first和last都没有溢出,如果使用 mid=(first+last)/2 的写法,first+last是有可能溢出的,而使用 mid=first+(last-first)/2 的写法就不会溢出。
假设全都为int型,上限为65535,first=45535,last=20001。则计算 mid=(first+last)/2 时会先计算括号里的数得到65536溢出了。而使用 mid=first+(last-first)/2 可以避免这种情况而达到相同的效果。

2.链接

mid=(left+right)//2, left+right 在Python中如果发生整型溢出,Python会自动转成长整形

3. 2的链接中,while low<high 的写法不懂,又查到其他资料

4.python自带函数可以直接实现

链接,会修改原始数据

def searchInsert(nums, target):        
    nums.append(target) # 不管这个数在不在里面,直接append        
    nums.sort() # 然后再排序        
    return nums.index(target) # 最后返回查找的index

链接

import bisect
def searchInsert(nums,target):
    left = bisect.bisect_left(nums,target)
    return left

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值