二分查找专项练习—— LeetCode 第 33、34、35 题

昨天没能完成 34,今天来补上。恰好第 35 题也是二分查找算法的应用,放到一起来记录。

首先看下二分查找算法的概念:

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
百度百科:二分查找

使用的题目中,一般会提到要求时间复杂度为 O(log n) 级别,以及涉及到的列表、数组是有序排列的。结合今天要记的三道题,我们来练习下这种解法的应用。在难度上,第 35 题简单,33、34 是中等难度,我们先看简单的。

题目一

第 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

题目分析

要在排序数组中找目标值的位置,很典型的二分查找的应用场景。当目标不存在时,返回目标应该被插入的位置。这个我们先把特殊情况择出来:列表长度不到 2 的情况,目标值大小超出列表值范围情况。正常二分查找的操作类似双指针法,定义一前一后两个索引,每次取其中间位置的值来进行判断,直到最终定位出结果。

比如示例 1,我们分别先取第一位 1 和最后一位 6 作为前后位置,此时中间位置为第 2 位 3,3 小于目标值,所以我们把范围缩小到右半部;缩小范围后,第 2 位 3 成了左侧边界,最后一位 6 仍是右边界,此时中间位置为 第 3 位 恰好为 5 目标值,所以返回第 3 位的坐标 2,任务完成。

这题要注意的点是,若存在目标值,返回其坐标;若不存在,要返回目标应该插入的位置。

代码实现

看二分法,通常都会纠结于比较完中点值后,对之后左右边界如何划分,究竟取 mid、mid-1 还是 mid+1 作为新的坐标,这个要具体来分析。

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
    	# 空列表情况
        if nums==[]:
            return 0
        length = len(nums)
        # 只有一个数的列表情况
        if length<2:
            if nums[0]>=target:
                return 0
            else:
                return 1
        # 目标值不在列表值范围内情况
        if target<=nums[0]:
            return 0
        if target> nums[-1]:
            return length
        
        # 二分查找法开始
        # 定义左右边界位置,最左端和最右端索引
        l,r = 0,length-1
        # while 循环控制 l 和 r 来缩小范围
        while l<r:
        	# 取中点,这里的取值会偏左,比如第 1、2 位取的中点是第 1 位
            mid = (l
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值