C语言每日亿题(三)

news2025/1/12 1:45:02

文章目录

    • 一.二分查找
    • 二.第一个错误的版本
    • 三.搜索插入位置

一.二分查找

原题传送门:力扣

题目:
在这里插入图片描述

在有序序列中查找,用二分的方法是非常有效的,但仅限于有序,如果是无序,二分查找是用不了的。

现在我直接来讲思路,在下面这个序列中找到8这个数字,并返回它的下标:
在这里插入图片描述

现在重点来了,先定义两个变量left,right来代表数组中的下标:
在这里插入图片描述

在定义一个变量,表示的也是下标,但它指向的元素是left,right指向的元素中间的位置:
在这里插入图片描述

现在判断要找的值(我们用key来表示,这里的key为8)和mid指向的元素哪个大,如果key>a[mid]是不是说明我们要找的值肯定在mid的右边,同理如果key<a[mid]说明要找的值肯定在mid左边。这里可以看到key是在mid右边。现在我们就可以更新一下left的值:

//把left更新到mid的左边一个位置上
left = mid + 1;

在这里插入图片描述

更新完left的值后,在更新mid的值,这里mid同样为left,right中间的位置:
在这里插入图片描述

此时发现mid指向的刚好是key的值,这时候说明找到该值了,因为要直到下标,而下标就是mid的值。

但是如果现在key的值是7呢?
在这里插入图片描述

其实也一样写,把right更新到mid前面一位就行,然后在更新mid的值。

right = mid - 1;

当然我们不可能执行一次就结束了,所以要写成一个循环,但是循环终止的条件是什么呢?
仔细观察可以看到,要么是left在向右移动,right再向左移动,也就是说指向left在right左边,就说明两个下标之间肯定有元素,有元素就说明还没有找完。所以终止条件无非就两种left > right的时候或者找到需要找的值的时候。

这里要注意必须是left > right因为除了left < right的时候,left==right的时候也要判断,因为很有可能key的值就是left,right相等的时候。如果循环条件写成left < right就会把这种条件忽略掉。

int search(int* nums, int numsSize, int target) {
    int begin = 0;
    int end = numsSize - 1;
    int mid = (begin + end) / 2;
    while (begin <= end)
    {
        if (nums[mid] < target)
            //说明此时要找的位置在中间位置右边
        {
            begin = mid + 1;
        }
        else if (nums[mid] > target)
            //说明此时要找的位置在中间位置左边
        {
            end = mid - 1;
        }
        else
            //如果相等说明找到了
        {
            return mid;
        }
        mid = (begin + end) / 2;
    }
    //循环结束还没有找到就返回-1
    return -1;
}

这里还有一个小细节,这里的mid的值我是这样写的:

int mid = (begin + end) / 2;

这样写虽然可以,但是有一定的风险,因为mid是int类型的,但此时begin,end都是很大的时候就很有可能得到的值mid装不下,导致发生错误。所以这里改进一下:

int mid = begin + (end - begin)/2;

二.第一个错误的版本

原题传送门:力扣

题目:
在这里插入图片描述

有序序列中查找常用的就是二分查找了。这题也不例外,假设这里有10个产品,同样定义三个变量来表示数组元素下标:
在这里插入图片描述

现在要找的第一个错误版本要保证它的前一个版本是正确的。这里假设第一个错误版本是8,所以mid和mid之前的版本都是正确的。现在就可以更新一下left的值,因为mid肯定是正确的了,所以left改到mid后面一个位置就行,然后更新mid的位置:
在这里插入图片描述

随后发现此时mid指向的版本号是错误的,说明此时mid或者mid的前几个里有一个是第一个错误的版本,此时改更新right的位置成mid,随后在更新mid:
在这里插入图片描述

当初假设的8是第一个错误版号,mid指向的版号是正确的,所以继续更新:

在这里插入图片描述

mid指向的仍然是正确版号,所以继续走:
在这里插入图片描述

因为不可能一次就把答案找到,肯定要把上面的步骤放在一个循环里,通过上图,循环的终止条件也显而易见了。下面这是答案代码:

int firstBadVersion(int n) {
    int left = 1;
    int right = n;

    while(left < right)
    {
        int mid = left + (right - left) / 2;
        //int mid = (left + right) / 2;
        if(isBadVersion(mid) == true)
            right = mid;
        else
            left = mid + 1;
    }
    return left;
}

三.搜索插入位置

原题传送门:力扣

题目:在这里插入图片描述

这其实和第一题的普通二分查找差不多,只是这里多了一个条件,如果在数组中找不到对应的target就把target插到对应的位置,并返回其下标。我们就看上面的三个例子就可以了,前两个例子可以不用管就是二分查找,现在主要看第三个例子:找不到target的情况。

做这一题可以先找规律,就当这个例三是个普通二分查找的题目,看看最后的情况和target有什么关系:
在这里插入图片描述

经过一系列变化,如果a[mid]<target,left更新到mid+1的位置,a[mid]>target,right更新到mid-1的位置,然后一直循环直到left >right时停下来.(上面这些都和第一题一样,这里就不细讲了)。最后的图:
在这里插入图片描述

按照第一题的写法,本应该走到这一步并跳出循环的时候应该要返回一个false,但是这里不同,如果你没有找到target是把target插入进去并把它的下标返回出来。但是通过上图可以发现,需要返回的答案其实就是left的值是吧。但是题目没说要检查target是否被插入到数组中,所以说如果没有找到直接返回left就行了:

int searchInsert(int* nums, int numsSize, int target){
    int left = 0;
    int right = numsSize - 1;
    int mid = (left + right) / 2;

    while (left <= right)
    {
        mid = (left + right) / 2;
        if (nums[mid] < target)
            left = mid + 1;
        else if (nums[mid] > target)
            right = mid - 1;
        else
            return mid;
    }
    return left;
}

有人可能会觉得,我上面举得例子是个巧合,只是刚好答案是left的值。其实不是的,这并不是一个巧合,while循环结束的条件是left > right,也就是说最后都没有找到target的时候肯定会跳出循环,而跳出循环后,left,right的关系肯定是left = right+1.而target要插入的位置肯定是循环里最后一次找的值的后面一个也就是right指向元素的后一个。所以答案自然就是left的值了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring cloud Ribbon负载均衡实战

Spring cloud Ribbon负载均衡一、简介二、负载均衡不同方案的区别1、集中式负载均衡&#xff08;服务器负载均衡&#xff09;2、进程内负载均衡&#xff08;客户端负载均衡&#xff09;三、负载均衡策略1、轮询策略&#xff08;默认&#xff09;2、权重轮询策略3、随机策略4、最…

导入vue+springboot前后端分离项目

1、环境 1、前端 nodejs 12.1.0vscode或者webstorm 2、后端 jdk1.8maven3.6.3&#xff08;3以上即可&#xff09;sqlyogidea 1、导入数据库 点击右键创建同名的数据库 将sql文件导入到数据库中 右键编辑文件&#xff0c;ctrla选中全部语句&#xff0c;ctrlc进行复制&…

Go 实现选择排序算法及优化

Go 实现选择排序算法及优化选择排序图片演示普通算法优化算法小结耐心和持久胜过激烈和狂热。 哈喽大家好&#xff0c;我是陈明勇&#xff0c;今天分享的内容是使用 Go 实现选择排序算法。如果本文对你有帮助&#xff0c;不妨点个赞&#xff0c;如果你是 Go 语言初学者&#xf…

一只脚踏入数据结构的大门,如何用C语言实现一个单链表(超超超详解,我的灵魂受到了升华)

目录 0.前言 1.什么是链表 1.1链表简介 1.2链表的分类 1.3为什么要有链表&#xff08;vs顺序表&#xff09; 1.3.1顺序表的缺点 1.3.2 链表的优点 1.3.3 顺序表的优点是链表的缺点 1.4.为什么选择实现结构最简单的单链表 2* 什么是单链表&#xff08;两种理解逻辑&…

window10+TensorRT-8.2.5.1+yolov5 v6.2 c++部署

一、准备工具 1.1、visual studio下载安装 参考&#xff1a;vs2019社区版下载教程&#xff08;详细&#xff09;_Redamancy_06的博客-CSDN博客_vs2019社区版 1.2、显卡驱动cudacudnn安装 参考&#xff1a;win10系统3060显卡驱动cuda11.5cudnn8.3安装_Bubble_water的博客-CS…

手写Spring3(Bean构造函数的类实例化策略)

文章目录目标项目结构一、代码实现1、新增getBean接口2、定义实例化策略接口3、JDK 实例化4、Cglib 实例化5、创建策略调用二、测试1、准备2、测试用例3、测试结果目标 上一篇文章&#xff0c;我们实例化对象&#xff0c;是通过无参的构造方式生成 所以今天是解决包含参数的构…

docker镜像的导入导出,并发布到服务器上

比如我本地的vue项目&#xff0c;先打包编译为一个镜像&#xff1a; docker build -t cvport . 不会编译的可以看我这篇文章&#xff1a;使用docker构建vue项目并成功运行在本地和线上_1024小神的博客-CSDN博客 开始将镜像保存为一个tar文件&#xff1a; docker save -o cvp…

基于java+springmvc+mybatis+jsp+mysql的高校学术交流平台

项目介绍 高校学术交流平台是基于java编程语言&#xff0c;mysql数据库&#xff0c;ssm框架&#xff0c;idea开发工具开发&#xff0c;本系统有管理员和用户两个角色&#xff0c;其中用户可以注册登陆系统&#xff0c;查看校园资讯&#xff0c;学术交流帖子&#xff0c;发布帖…

Akka 学习(五)消息传递的方式

目录一 消息传递方式1.1 消息不可变1.2 ASK消息模式1.3 Tell消息模式1.4 Forward消息模式1.4 Pipe消息模式有4种核心的Actor消息模式&#xff1a;Tell、Ask、Forward和Pipe。一 消息传递方式 在这里&#xff0c;将从Actor之间发送消息的角度来介绍所有关于消息传递的概念。 ● …

【多线程(六)】并发工具类的基本使用、ConcurrentHashMap1.7版本及1.8版本底层原理分析

文章目录6.并发工具类6.1 并发工具类-Hashtable6.2 并发工具类-ConcurrentHashMap基本使用6.3 并发工具类-ConcurrentHashMap1.7原理6.4 并发工具类-ConcurrentHashMap1.8原理6.5 并发工具类-CountDownLatch6.6并发工具类-Semaphore总结6.并发工具类 6.1 并发工具类-Hashtable…

一文看懂MySQL中order by排序语句的原理

order by 是怎么工作的&#xff1f; 表定义 CREATE TABLE t1 ( id int(11) NOT NULL, city varchar(16) NOT NULL, name varchar(16) NOT NULL, age int(11) NOT NULL, addr varchar(128) DEFAULT NULL, PRIMARY KEY (id), KEY city (city)) ENGINEInnoDB;SQL语句可以…

零基础入门JavaWeb——Vue的生命周期

一、概念 在编程领域&#xff0c;生命周期是一个很常见的概念。一个对象从创建、初始化、工作、释放、清理和销毁&#xff0c;会经历很多环节的演变。 二、Vue对象的生命周期 三、生命周期钩子函数 Vue允许在特定的生命周期环节中通过钩子函数加入我们的代码。 3.1 示例代码…

基于双向LSTM模型进行电力需求预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f389;作者研究&#xff1a;&#x1f3c5;&#x1f3c5;&#x1f3c5;主要研究方向是电力系统和智能算法、机器学…

尚硅谷笔记——求和案例纯react版、redux精简版

家人们天气冷啦注意保暖呀&#xff0c;不要像我一样因为冷而不想起床学习&#xff0c;冬日里也不能放弃训练 看了两遍尚硅谷的redux课程&#xff0c;把reduc案例代码重新敲了一次为了加深印象还是写个播客把&#xff0c;强烈推荐大家看尚硅谷课太细致啦 redux 是什么&#x…

即将到来的2023,国内元宇宙开始“割”企业了?

元宇宙爆火一年后&#xff0c;UTONMOS即将成为全球化全部实现ERC-721协议NFT链上垂直游戏价值生态的系统平台&#xff0c;旨在通过利用自身所拥有的各类头部资源和游戏化打造内容层的融合&#xff0c;建立一个元气满满的元宇宙Web3.0平台。 通过数字藏品技术的应用&#xff0c…

Flask框架

Flask一 前言二 快速使用三 内置配置变量四 配置文件的写法五 路由六 cbv写法6.1 快速使用6.2 cbv加装饰器6.3 as_view的执行流程6.4 as_view的name参数6.5 继承View写cbv七 模板语法7.1 渲染变量7.2 变量的循环7.3 逻辑判断一 前言 Flask是一个基于Python开发并且依赖jinja2模…

Fluent中模型设置和数据的复用

1 背景 在实际工程中&#xff0c;必然存在利用仿真比较各类设计方案优劣的场景。 对于复杂模型&#xff0c;逐个设置各个设计方案的仿真模型并从头开始计算结果&#xff0c;既易错也耗时。因此需要通过模型设置和数据的复用&#xff0c;达到防错和提高工作效率。 2 模型设置复…

基于Docker做MySQL主从搭建与Django的读写分离

目录 基于Docker做MySQL主从搭建 django读写分离 基于Docker做MySQL主从搭建 主从的作用&#xff1a;写数据数据时使用主库&#xff0c;从库只用来读数据&#xff0c;这样做能够减少数据库压力&#xff0c;主从搭建可以一主一从&#xff0c;也可以是一主多从。 mysql主从配…

肝2022世界杯,怒写企业级镜像私仓Docker+Harbor实践

2022-12-09 揭幕2022卡塔尔世界杯4强角逐的第一天&#xff0c;越来越精彩了 同时记录程序猿的成长~ 1.背景 由于期望搭建一个企业级CICD的环境&#xff0c;开始尝试常规的gitlabjenkinsk8sdocker harborspringboot开始练手 其中版本如下&#xff1a; 1.gitlab: GitLab Com…

天权信安catf1ag网络安全联合公开赛---wp

文章目录misc简单隐写十位马WebhistoryCrypto疑惑ezrsapasswdre遗失的物品misc 简单隐写 丢进kali binwalk 分离一下 得到一个加密的压缩包 内含flag.txt 使用jphs无密码得到一个txt 得到password:catf1agcatf1agcatf1ag 解压压缩包得到一串字符串 dbug1bh{KQit_x1o_Z0v_…