代码随想录算法训练营第一天 | 704. 二分查找、 27. 移除元素、977.有序数组的平方 (上)

news/2024/10/21 11:28:36

1-704.二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1


示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2 输出: -1 解释: 2 不存在 nums 中因此返回 -1

提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

 

二分查找问题的关键在于边界条件的选择决定了判断条件的设置。以下从左闭右闭区间和左闭右开区间两种写法来说明。这里其实有一点,就是题目给出的是左闭右闭也好,左闭右开也好,都可以使用两种解法,不会影响。

左闭右闭:即left的值和right的值都可以取到,二分查找是在单调数列中,通过不断判断中间值的方法来逐渐缩小所查的范围。某种意义上和猜数字的游戏类似,只不过我们固定了每次都猜中间数字。这样可以最高效率猜到这个数字的位置。

在左闭右闭的情况下,我们定义left为0,right为数组大小-1,这样可以让right的编号正好对应数组的最后一个值,也就是取满数组。

第二步,考虑最外的大循环,当left和right非常接近的时候就可以停止循环了。在闭区间中,left是可以等于right的,于是我们设置判断条件为left<=right,只有当left大于right时退出循环。

第三部,在大循环内部我们需要根据target的位置来选择更新left或right。这里我们需要定义middle的值为(left+right)/2。这一步我看很多人说可以定义为left+(right-left)/2,可以防止溢出,我其实不太理解,个人认为可能是如果当right太大的时候两个数相加会超过int的范围。

定义好middle后,我们比较原数组在middle位置的数值和target,当大于target的时候,说明目标数在left和middle中间,于是我们需要更新right值,此时由于我们选择了左闭右闭区间,middle位置的数确定不是target了,那么right就可以等于middle-1,因为我们不需要重复判断middle,可以直接把它排除在外。

当小于target也是同理,说明目标数在middle和right中间,于是我们更新left的值,和前面同样道理,并不需要将middle放入我们待判断的区间中,于是left可以为middle+1。

那么其他情况显然middle等于target,此时输出middle即可。大循环后return-1即可。代码如下:

class Solution {
public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;//左闭右闭区间,right直接对应数组最后一个元素的序号即可while(left <= right){ // 当left==right,区间[left, right]依旧合法,用 <=int middle = left + ((right - left) / 2);//防止溢出,大概是防止int型不够存if(nums[middle] > target){right = middle - 1;// target 在左,将已经判断过的middle排除,所以[left, middle - 1]}else if(nums[middle] < target){left = middle + 1; // target 在右,将已经判断过的middle排除,所以[middle + 1, right]}else{return middle;// 找到目标} }// 未找到目标时return -1;}
};

左闭右开:

道理和前一种类似,代码如下:

class Solution {
public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size();//左闭右开区间,right需要对应数组最后一个元素的序号+1来保证能遍历题目闭区间数组中所有的数while(left < right){ // 当left=right,区间[left, right)不合法,用 <int middle = left + ((right - left) / 2);//防止溢出,大概是防止int型不够存if(nums[middle] > target){right = middle;// target 在左,将已经判断过的middle排除,所以[left, middle)}else if(nums[middle] < target){left = middle + 1; // target 在右,将已经判断过的middle排除,所以[middle + 1, right)}else{return middle;// 找到目标} }// 未找到目标时return -1;}
};

35.搜索插入位置 和 34. 在排序数组中查找元素的第一个和最后一个位置 ,这俩明天再看。

2-27.移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
  • 返回 k

用户评测:

评测机将使用以下代码测试您的解决方案:

int[] nums = [...]; // 输入数组
int val = ...; // 要移除的值
int[] expectedNums = [...]; // 长度正确的预期答案。// 它以不等于 val 的值排序。int k = removeElement(nums, val); // 调用你的实现assert k == expectedNums.length;
sort(nums, 0, k); // 排序 nums 的前 k 个元素
for (int i = 0; i < actualLength; i++) {assert nums[i] == expectedNums[i];
}

如果所有的断言都通过,你的解决方案将会 通过

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,_,_]
解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,_,_,_]
解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。
注意这五个元素可以任意顺序返回。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

提示:

  • 0 <= nums.length <= 100
  • 0 <= nums[i] <= 50
  • 0 <= val <= 100 

     

 

涉及数组概念相关问题,简单的暴力解法为,直接两层循环,第一层寻找元素并删除,第二层将所有元素提前一位即可。下面给出代码:

class Solution {
public:int removeElement(vector<int>& nums, int val) {int size = nums.size();for (int i = 0;i < size; i++){if (val == nums[i]){for(int j = i + 1; j < size; j++){nums[j - 1] = nums[j];}i--;size--;}}return size;}
};

今天目前先到这里,27的双指针实现和977题目明天一起做。

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

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

相关文章

基于BP神经网络的苦瓜生长含水量预测模型matlab仿真

1.算法运行效果图预览 (完整程序运行后无水印)T表示温度,v表示风速,h表示模型厚度 2.算法运行软件版本 matlab2022a3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)for i = 1:13;figure;subplot(211);plot(y1{i},ro);hold onplot(Train_output1{i},b);xlabel(…

小车侧方位停车过程的动态模拟matlab仿真

1.课题概述小车侧方位停车过程的动态模拟matlab仿真。仿真得到小车的停车动画,小车移动的xy轴坐标以及角度变换。2.系统仿真结果 3.核心程序与模型 版本:MATLAB2022a%阶段3 %车轮 pause(1); for i=1:13ya1=ya1+0.5;yb1=yb1+0.5;ya2=ya2+0.5;yb2=yb2+0.5;cla; patch([Car…

实现dnmp中多站点多版本php并存

实现dnmp中多站点多版本php并存 PHP多版本部署之docker方式 背景 搞了一段时间Python,这两天又要开始做一些PHP相关的项目了,本地开发环境、测试环境、线上环境都需要重新弄了,为了开发方便还是决定用Docker方式来部署,自己又不想写Dockfile和compose文件啥的。于是找了下,…

数据采集实践第一次作业

目录作业①:定向爬取大学排名信息实验要求及结果心得体会作业②:商城商品比价定向爬虫实验要求及结果心得体会作业③:爬取网页中的JPEG和JPG格式图片实验要求及结果心得体会码云连接作业①:定向爬取大学排名信息 实验要求及结果要求 用requests和BeautifulSoup库方法定向爬…

mysql学习笔记3

通过Node-red对mysql数据库进行操作 1、环境配置 操作系统 宿主机:UBUNTU 虚拟环境:KVM 虚拟机1:Armbian 虚拟机2:Debian 网络 虚拟网络(默认的default配置): +-------------------+ +-------------------+ | | | …

这十年我与广告不共戴天练就的十八般武艺 #PC去广告 #手机去广告

背景大家应该都体会过广告的苦恼,比如看着好看的电视,突然给播放广告,这时候痛苦系数飙升。随着社会进步,广告的载体,还有形式也越来越多,比如手机端各种APP启动广告,PC端软件弹窗,网站Banner等,这些广告最主要的目的就是诱骗你误操作点击,然后陷入几乎无限弹窗的循环…

产品经理不会画架构图

在当今竞争激烈的科技行业中,产品经理扮演着至关重要的角色。他们是产品的灵魂人物,负责从概念提出到产品上线的整个过程。然而,有一个问题常常困扰着许多产品经理,那就是不会画架构图。在一些团队中,产品经理不会画架构图可能会遭到同事的质疑甚至群嘲。这不仅会影响产品…

CI/CD主流技术

软件持续集成/持续部署(CI/CD)阶段的主流技术1. 代码管理:Git(常用平台如 GitHub, GitLab, Bitbucket)SVN(Subversion)2. 单元测试:JUnit(Java)PyTest(Python)Jest(JavaScript/Node.js)NUnit(C#)3. 构建打包:Maven(Java)Gradle(Java、Kotlin)npm / Yarn(…