二分查找两个模板,leetcode35.搜索插入位置

这篇具有很好参考价值的文章主要介绍了二分查找两个模板,leetcode35.搜索插入位置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

二分法思想

在有序数列中,查找某个元素是否存在
扩展一下: 在有序数列中(通常是非递减,可以有重复元素),查找第一个满足xx条件的元素
每次搜索区间减半,时间复杂度 O ( l o g n ) O(logn) O(logn)

模板1:有序数组中,查找是否存在某个元素,找到返回位置,找不到返回-1

public int binarySearch(int[] nums, int target) {
    //初始左、右边界,覆盖完整位置
    int left = 0;
    int right = nums.length - 1;
    int mid;
    while (left <= right) {
        mid = left + (right - left) / 2; // 避免int溢出
        if (nums[mid] == target) {
            return mid;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}

1.初始边界为0和n-1,如果你的下标从1开始,那就是1和n,效果一样,只需要确保初始闭区间一定能覆盖可能的位置
2.更新机制,匹配就返回mid,否则mid+1或mid-1。区间更新时不用带上mid,因为当前mid位置不匹配,所以mid不在下一轮查询的考虑范围之内。
3.深究一下: 条件为什么是left<=right?
如果条件改成left<right,考虑一种情况:target=4,数组为1,2,3,4,5,left=2指向3,right=3指向4,进入循环:
mid=2,nums[mid]<target
left=3
此时left==right,退出循环,返回-1。没找到,错误!!
而如果条件是left<=right:
mid=3
nums[mid]==target,成功找到!

所以单纯找元素是否存在,条件是<=

模板2:有序数组中(非递减,可以有重复元素),查找第一个满足xx条件(以>=5为例)的元素的位置。如果不存在,给出假设该元素存在的正确位置。

public int binarySearch(int[] nums) {
	int target = 5;//例子,找第一个>=5
    int left = 0;
    int right = nums.length;//注意没有-1
    int mid;
    while (left < right) {
        mid = left + (right - left) / 2;
        if (nums[mid] >= target) {//这里就是条件
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}

与模板1相比,有4个区别:
1.初始right,多一个
2.循环条件,是<不是<=
3.边界更新机制
4.返回值

1.初始right为什么不-1? 因为要考虑所有可能得位置,如果target不存在,且比数组中所有元素都要大,那应该插入到最后一个位置,是n,不是n-1。
2、3、4举一个例子说明:1,2,3,5,6找4
初始left=0指向1,right=5指向6后面
mid=2, 3<4,left=3
mid=4, 6>4, right=4
mid=3, 5>4, right=3
left==right,退出循环
返回left=3
以上过程是正确的

如果循环条件是<=呢?
left=3, right=3
mid=3, 5>4, right=3

死循环了

再解释一下更新机制:
当nums[mid]>=target,因为我们要找第一个满足条件的,有可能在mid之前吧,所以要在left~mid搜索。但mid之前也有可能没啦,所以搜索区间不能把mid丢了。 因此更新方法为right=mid
当nums[mid]<target,显然mid不满足,答案一定是>=mid+1,区间更新时不需要再保留mid了。
一句话概括:更新下一轮循环的左、右时,一定要保证[左, 右]这个闭区间能覆盖所有的答案可能位置。

咱们这个模板是闭区间实现的,也有开区间的版本,自行研究。

最后说明一下返回值,
返回left,其实并不保证nums[left]==target。若target不存在,left是假设存在,该插在的位置。
因此,如果需要确定有没有搜索到,还得判断一下返回值nums[left]==target

基于模板2,如果要找最后一个满足xx条件的呢?

刚刚已经强调了,模板2处理的是找第一个满足xx条件的元素。
怎么找最后一个满足的呢?
很简单,问题转化成:找第一个不满足xx条件的元素位置,找到的位置-1文章来源地址https://www.toymoban.com/news/detail-829276.html

到了这里,关于二分查找两个模板,leetcode35.搜索插入位置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 35. 搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1:   输入: nums = [1,3,5,6], target = 5   输出: 2 示例 2:   输入: nums = [1,3,5,6], target = 2   输出

    2024年02月08日
    浏览(11)
  • [二分查找]LeetCode2040:两个有序数组的第 K 小乘积

    二分查找算法合集 给你两个 从小到大排好序 且下标从 0 开始的整数数组 nums1 和 nums2 以及一个整数 k ,请你返回第 k (从 1 开始编号)小的 nums1[i] * nums2[j] 的乘积,其中 0 = i nums1.length 且 0 = j nums2.length 。 示例 1: 输入:nums1 = [2,5], nums2 = [3,4], k = 2 输出:8 解释:第 2 小的乘

    2024年02月04日
    浏览(15)
  • 代码随想录额外题目| 数组03 ●34排序数组查首尾位置 ●922按奇偶排序数组II●35搜索插入位置

    #34排序数组查首尾位置 medium,我写的:1 暴力 我写的,做了个类似二分搜索的方法: 随想录:从两头都做类似二分搜索 #922 按奇偶排序数组II 我的解法,有点蠢: inplace解法: 把odd idx放的偶数,给换到even idx放的奇数 注意j是从1开始,而且每轮i,j都是继续增加不回去 空间表

    2024年02月15日
    浏览(12)
  • LeetCode-74. 搜索二维矩阵【数组 二分查找 矩阵】

    给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。 示例 1: 输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]],

    2024年04月14日
    浏览(13)
  • 看完这篇文章你就彻底懂啦{保姆级讲解}-----(LeetCode刷题704、35、34数组二分查找) 2023.4.17

    本文章一部分内容参考于《代码随想录》----如有侵权请联系作者删除即可,撰写本文章主要目的在于记录自己学习体会并分享给大家,全篇并不仅仅是复制粘贴,更多的是加入了自己的思考,希望读完此篇文章能真正帮助到您!!! 数组是由n(n=1)个 相同类型 的数据元素

    2024年02月05日
    浏览(15)
  • leetcode-搜索插入位置

    35. 搜索插入位置 此题使用的是二分查找 二分查找的前提条件: 1.数组是有序的;2.数组中无重复元素,一旦出现重复元素,则返回的元素下标可能不是唯一的 二分查找涉及的边界问题比较多,比如当前这道题,到底是while left right呢还是while left = right呢?到底是right = mid呢还

    2024年02月02日
    浏览(10)
  • LeetCode-1483. 树节点的第 K 个祖先【树 深度优先搜索 广度优先搜索 设计 二分查找 动态规划】

    给你一棵树,树上有 n 个节点,按从 0 到 n-1 编号。树以父节点数组的形式给出,其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。 树节点的第 k 个祖先节点是从该节点到根节点路径上的第 k 个节点。 实现 TreeAncestor 类: TreeAncestor(int n, int[] parent) 对树和父

    2024年04月16日
    浏览(12)
  • 二分查找--查找整数位置

    描述 二分查找 又叫 折半查找。它采用的是\\\"分治策略\\\"。 给出非降序排列的 n 个整数,查找是否存在某个整数,如果存在,则输出其位置。 输入描述 第一行是一个整数 n(0n≤200000) 表示整数的个数。 接下来是 n 个整数,每个整数之间用一个空格分隔。 接下来一行是一个

    2024年02月13日
    浏览(11)
  • 【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

    《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌ 更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍 感谢小伙伴 们点赞、关注! class   Solution :      def   mySqrt ( self ,  x :   int )   -   int :       

    2024年02月04日
    浏览(19)
  • 【二分查找】一文带你掌握二分法 (附万能模板)

    一、简介 哪怕没有学过编程的同学,也许不知道二分法这个名字,但也一定接触过它的核心思想。不了解的同学也没关系,我用一句话就能概括出它的精髓: 将一个区间一分为二,每次都舍弃其中的一部分。 二分法能够极大地降低我们在解决问题时的时间复杂度。假如你要

    2024年01月19日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包