首页 > 其他分享 >【秋招刷题打卡】Day02-二分系列之-二分查找

【秋招刷题打卡】Day02-二分系列之-二分查找

时间:2024-06-22 19:59:04浏览次数:26  
标签:二分 target nums int 招刷题 mid 端点 打卡 check

Day02-二分系列之-二分查找

前言

给大家推荐一下咱们的 陪伴打卡小屋 知识星球啦,详细介绍 =>笔试刷题陪伴小屋-打卡赢价值丰厚奖励 <=

⏰小屋将在每日上午发放打卡题目,包括:

  • 一道该算法的模版题 (主要以力扣,牛客,acwing等其他OJ网站的题目作为模版)
  • 一道该算法的应用题(主要以往期互联网大厂 笔试真题 的形式出现,评测在咱们的 笔试突围OJ

在这里插入图片描述

小屋day02

我们预计花三天的时间来介绍和巩固二分的题目,其中包括

  • 二分查找
  • 二分答案
  • 二分最大化最小值/最小化最大值

其中笔试常考的为后两类,今年春招中出现了不下 10 次。

引言

举个二分的例子

比如有一个有序单调不减的数组 a r r arr arr,以及一个目标值 X X X ,要求在 a r r arr arr 中找到第一个 ≥ X \ge X ≥X 的数。

做法:每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需到右侧查找;如果中间元素大于所查找的值同理,只需到左侧查找。

通过二分搜索能够有效的帮原本 O ( n ) O(n) O(n) 遍历数组的时间复杂度降为 O log ⁡ ( n ) O \log(n) Olog(n)。

当然二分能做的事远远不止如此,一个题目,如果一个区间具有单调性质,那么一定可以二分,但是如果说这道题目没有单调性质,而是具有某种区间性质的话,我们同样可以使用二分,二分的题目,往往会出现最大值最小值, 或者单调性质。题目如果出现最大的最小值最小的最大值的类似的字眼,一般是可以使用二分来解决。

✨ 以下提供一个,本人长期使用的一个比较好用的手写二分模版

二分模版

二分模板一共有两个,分别适用于不同情况,使用时只需修改check函数即可。
算法思路:假设目标值在闭区间 [l, r] 中, 每次将区间长度缩小一半,当 l = r 时,我们就找到了目标值。

版本1

当我们将区间[l, r]划分成[l, mid][mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加 1。

  • CPP

    int bsearch_1(int l, int r)
    {
      // l 为左端点,r 为右端点,都是闭区间
      // 使用时只需修改check函数即可
        while (l < r)
        {
            int mid = l + r >> 1;
            if (check(mid)) r = mid; // check函数代表你需要进行的判断操作
                                       // 最终的答案会满足check条件
            else l = mid + 1; // 一定是这么写 不用多想
        }
        return l; // 此时的 l 为答案 (l == r)
    }
    
  • Java

    public int bsearch_1(int l, int r) {
       // l 为左端点,r 为右端点,都是闭区间
      // 使用时只需修改check函数即可
        while (l < r) {
            int mid = (l + r) >> 1;
            if (check(mid)) {
                r = mid; // check函数代表你需要进行的判断操作
                         // 最终的答案会满足check条件
            } else {
                l = mid + 1; // 一定是这么写 不用多想
            }
        }
        return l; // 此时的 l 为答案 (l == r)
    }
    
  • Python

    def bsearch_1(l, r):
       # l 为左端点,r 为右端点,都是闭区间
      # 使用时只需修改check函数即可
        while l < r:
            mid = (l + r) // 2
            if check(mid):
                r = mid # check函数代表你需要进行的判断操作
                        # 最终的答案会满足check条件
            else:
                l = mid + 1 # 一定是这么写 不用多想
        return l # 此时的 l 为答案 (l == r)
    
版本2

当我们将区间[l, r]划分成[l, mid - 1][mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

  • CPP

    int bsearch_2(int l, int r)
    {
       // l 为左端点,r 为右端点,都是闭区间
      // 使用时只需修改check函数即可
        while (l < r)
        {
            int mid = l + r + 1 >> 1; // 注意这里要多加 1
            if (check(mid)) l = mid; // check函数代表你需要进行的判断操作
                                      // 最终的答案会满足check条件
            else r = mid - 1; // 一定是这么写 不用多想
        }
        return l; // 此时的 l 为答案 (l == r)
    }
    
  • Java

    public int bsearch_2(int l, int r) {
       // l 为左端点,r 为右端点,都是闭区间
      // 使用时只需修改check函数即可
        while (l < r) {
            int mid = (l + r + 1) >> 1;// 注意这里要多加 1
            if (check(mid)) {
                l = mid; // check函数代表你需要进行的判断操作
                         // 最终的答案会满足check条件
            } else {
                r = mid - 1; // 一定是这么写 不用多想
            }
        }
        return l; // 此时的 l 为答案 (l == r)
    }
    
  • Python

    def bsearch_2(l, r):
       # l 为左端点,r 为右端点,都是闭区间
      # 使用时只需修改check函数即可
        while l < r:
            mid = (l + r + 1) // 2 # 注意这里要多加 1
            if check(mid):
                l = mid # check函数代表你需要进行的判断操作
                        # 最终的答案会满足check条件
            else:
                r = mid - 1 # 一定是这么写 不用多想
        return l # 此时的 l 为答案 (l == r)
    
什么时候使用版本1 or 2?

清隆这边给大家总结了一下:

  • 如果在 if(check()) 判断之后需要 跟新(左移) 右端点的,用 版本1
  • 反之,如果是需要 跟新(右移) 左端点的,用 版本2

接来下我们看看模版如何运用

标签:二分,target,nums,int,招刷题,mid,端点,打卡,check
From: https://blog.csdn.net/Qmtdearu/article/details/139887328

相关文章

  • 二分查找
    二分查找算法思想有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功。一个情景:将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于......
  • 打卡信奥刷题(132)用Scratch图形化工具信奥P9913 [普及组]「RiOI-03」water problem
    「RiOI-03」waterproblem题目描述给定一个正整数nnn,问一个正方形能否被分割为nn......
  • 基于微信小程序的健身小助手打卡预约教学系统(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • 704. 二分查找 27. 移除元素
    704.二分查找题目链接:https://leetcode.cn/problems/binary-search/ 前置条件:数值有序 效果:可以将时间复杂度优化为log(n) 思路:target(可能存在的)元素等于mid位元素时,返回当前下标target元素相对于mid位元素小时,选择左侧区域继续查找t......
  • 【MindSpore学习打卡】初学教程-04数据集 Dataset-使用MindSpore实现高效数据加载与预
    在深度学习的世界里,数据是模型训练的根基。高质量的数据输入不仅能提升模型的性能,还能加速训练过程。MindSpore提供了一个强大的数据引擎,通过数据集(Dataset)和数据变换(Transforms)实现高效的数据预处理。本文将详细介绍如何使用MindSpore加载和处理数据集,并通过具体的示例......
  • 【MindSpore学习打卡】初学教程-03张量Tensor-理解MindSpore中的张量(Tensor)操作
    03张量Tensor-理解MindSpore中的张量(Tensor)操作在深度学习领域,张量(Tensor)是最基本的数据结构之一。它不仅可以表示标量、向量和矩阵,还可以表示更高维度的数据。张量在神经网络的构建和训练中扮演着至关重要的角色。在MindSpore中,张量是网络运算的基本单位。本篇博客将详......
  • Day57 代码随想录打卡|二叉树篇---修建二叉搜索树
    题目(leecodeT669):给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low,high]中。修剪树 不应该 改变保留在树中的元素的相对结构(即,如果没有被移除,原有的父代子代关系都应当保留)。可以证明,存在 唯一的答......
  • 代码随想录Day1-二分查找法|快慢指针
    二分查找题目链接二分查找是一个较为基础的查找方式,对一个有序没有重复值的数组进行查找时,能够提供一个较好的时间复杂度\(O(log(n))\)算法概要对于有序并且没有重复值的数组来说,我们可以首先选定整个数组的中间下标,它的值则称为中间值,通过它把大数组分成两个小的数组,其中一个......
  • 【题解】CF1949B | 二分答案 霍尔定理
    本题可以做到低于\(O(n^2)\)。最大化最小值,考虑二分答案\(v\)变为检查可行性:每个主菜匹配的开胃菜的两个值都要在\((-\infty,x-v],[x+v,+\infty]\)间选取,问是否存在主菜与开胃菜的完美匹配。对开胃菜排序,得到第\(i\)个主菜可以匹配到的开胃菜集合为一个后缀和一个前缀:\([......
  • 昇思25天学习打卡营第1天 | 快速入门
    官网完整版代码详解题外话:这几天人工智能实训,在学深度学习,我觉得蛮像的过程理解:1.数据预处理1.1load数据集1.2查看数据集对象的结构和类型1.3数据变换MindSpore的dataset使用数据处理流水线(DataProcessingPipeline),需指定map、batch、shuffle等操作。使用map对图像数据......