【leecode】第35题:搜索插入位置

 题目:

给定一个排序数组 nums 和一个目标值 var ,在数组中找到目标值,并返回其索引

如果目标值不存在数组中,返回它将会被按顺序插入的位置

题目链接:搜索插入位置


题目限制:

必须使用时间复杂度为O(log n)的算法


解题思路:

目标值只有四种情况:

        1、目标值在数组所有元素之前

        2、目标值等于数组某个元素

        3、目标值不在数组中,需要插入到指定位置

        4、目标值在数组所有元素之后

利用二分法来先求中位数,设:

左指针等于数组第一个元素,既:left = nums[0];

右指针等于数组最后一个元素,既:right = [nums[-1]];

再把目标值和中位数作对比,既:

  • median = (left + (right + left))  // 2
  • 左指针 <= 右指针
  • var < median 时,求值范围为:[左指针,median-1]
  • var > median 时,求值范围为:[median+1,右指针]
  • var = median 时,满足情况2

利用中位数对比 var 值,可减少遍历元素,从而达到时间复杂度为O(log n)


实现代码:

class Solution:
    def searchInsert(self, nums: List[int], var: int) -> int:
        left, right = 0, len(nums) - 1              # 左指针等于nums[0],右指针等于num[-1]

        while left <= right:                        # 当left = right 时,nums元素只剩下一个
            median = left + ((right - left) // 2)         # 取数组的中位数,每次判断var时,中位数会跟随条件而变动

            if nums[median] < var:                  # 如果 var 值大于中位数时
                left = median + 1                   # var 值的取值范围为[median+1,right]
            elif nums[median] > var:                # 如果 var 值小于中位数时
                right = median - 1                  # var 值的取值范围为[left,median-1]
            else:
                return median                       # 以上都不满足时,var = 中位数
        # 不断缩小 var 值的取值范围,直到满足 left > right 时
        return right + 1                            # 把 var 插入当前right元素的下一个位置

代码执行逻辑:

满足 left <= right 条件时,不断循环,直到left > right,既nums中没有等于var的值

计算当前nums的中位数位置

比较当前中位数位置的元素与var值,既筛选掉一半不符合条件的元素

        若var值大,则意味着var值比当前中位数的元素还要大,把var最小值取值范围移动到中位数元素的后一位

        若var值小,则意味着var值比当前中位数的元素还要小,把var最大值取值范围移动到中位数元素的前一位

        若var值等于中位数的元素,意味着nums的中位数位置等于var值

每判断一次,左或右指针会移动一个位置,只要满足循环条件,就会不断缩小var值的范围,直到left > right

注意:left > right 时,意味着nums中不存在等于var的值,这时,var要么小于数组中的所有元素,要么大于数组中的所有元素

按题目要求,把var插入最后一次满足条件 left <=right 中,既:当前的right + 1

可代入nums = [0,3,5,6] 和 [1,3,5,6] 试下


结论:

双指针的用法思路是:

确定数组长度以及边界问题,罗列数据的边界情况

找到中位数的位置,通过中位数作为边界,可以减少一半的元素,既:空间复杂度O(log n)

确定遍历循环退出条件

梳理遍历循环过程中 双指针和中位数的变动及其条件

循环结束,返回所需值或数组


LeetCode相关指针题:

【leecode】第27题:移除元素_inganxu-优快云博客

【leecode】第1题:两数之和_inganxu-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

inganxu

感谢您的支持!!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值