day 1 | 704. 二分查找、27. 移除元素
目录:
学习链接
题目链接:
https://leetcode.cn/problems/binary-search/
https://leetcode.cn/problems/remove-element/
文章链接:
数组理论基础:https://programmercarl.com/数组理论基础.html#数组理论基础
时间复杂度基础:https://programmercarl.com/前序/关于时间复杂度,你不知道的都在这里!.html
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
视频讲解:
https://www.bilibili.com/video/BV1fA4y1o715
https://www.bilibili.com/video/BV12A4y1Z7LP
第一想法
二分查找
需要找到升序数组中目标值的序号,没有则返回-1。算法的复杂度为O(log n)。
如果暴力求解的话,从头找到尾,那算法复杂度应该是O(n)。这题用二分法来求解,先找到中间的值,进行判断。之后根据大小选择是左边还是右边部分,一直这样分下去,最后找到目标值。
移除元素
给出一个数组nums和一个整数val,要求删除数组中所有的val,然后返回剩下的数组k的长度和数组。
题目还有要求,不要为另一个数组额外分配空间,所以是就在这个数组上进行操作。
思考1: 暴力求解,从前往后或者从后往前遍历,如果数组中有值等于val,那么直接将后面的所有往前移一位。直到遍历完。
思考2:无
看完代码随想录之后的想法
二分查找
区间的定义就是不变量,那么在循环中坚持根据查找区间的定义来做边界处理,就是循环不变量规则。
要注意是按照左闭右闭的思路写的还是按照左闭右开的思路写的。
主要是因为**.size()函数可以返回容器中实际数据的个数,也就是向量数组的长度。**比如数组长度为6,但是由于从0开始技术,num[6] 是不存在的。所以根据右边区间在哪个位置,就有两种写法。
主要实现代码:
区间取左闭右闭的情况
class Solution {public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size()-1;while(left<=right){int mid = left + (right-left)/2;if(target<nums[mid]){//当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1right = mid-1;}else if(target>nums[mid]){//当前这个nums[middle]一定不是target,那么接下来要查找的右区间结束下标位置就是 middle + 1left = mid+1;}else{return mid;}}//未找到目标值return -1;}
};
区间取左闭右开的情况
class Solution {public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size();while(left<right){int mid = left + ((right-left)>>1);if(target < nums[mid]){right = mid;}else if(target > nums[mid]){left = mid + 1;}else{return mid;}}//未找到目标值return -1;}
};
两个方法实现的用时和内存消耗情况:
上面为左闭右开情况,下面为左闭右闭情况。可以看到,当使用左闭右开区间时,运行速度更快,初步推测是因为左闭右闭在while中,比左闭右开的情况多了移步的操作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1P9VGkLO-1684937370361)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/90eed747-80ff-4654-9f51-9f97001a1c62/Untitled.png)]
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
移除元素
题目:给你一个数组 nums
**和一个值 val
,你需要 原地 移除所有数值等于 val
**的元素,并返回移除后数组的新长度。
暴力解法,就是找到对应元素后,将后面所有的元素往前移一位。
这里有个坑,下面代码中,第二个for循环,j的初始值选取,如果直接等于i,需要注意数组的长度问题。要往后选大的一位。除此之外,还要注意找到对应元素并移除后,下标需要再退到之前的一位,并且总长度要减少1.
暴力解法:
class Solution {public:int removeElement(vector<int>& nums, int val) {int length = nums.size();for(int i = 0; i < length; i++){if(nums[i] == val){//for(int j = i; j<length-1;j++){ //这种写法需要额外关注一下数组长度,会超标,所以减1// nums[j] = nums[j+1];// } for(int j = i+1; j<length;j++){nums[j-1] = nums[j];}i--;length--;}}return length;}
};
双指针法(快慢指针法):
通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
没有碰到要删除的值的时候,两个指针一起走,一直用快的指针给慢的指针赋值。碰到要删除的元素时,慢的指针停下,快的指针继续走一步,之后又同时赋值。确实牛逼。
class Solution {public:int removeElement(vector<int>& nums, int val) {int slowindex = 0;for(int fastindex = 0 ; fastindex < nums.size(); fastindex++){if(val != nums[fastindex]){nums[slowindex++] = nums[fastindex];}}return slowindex;}
};
虽然两者运行时间差不多,但是暴力求解的时间复杂度为O(n^2),而双指针法的时间复杂度仅为O(n)。数据量大的时候就能有明显差距。
实现过程中遇到哪些困难
1、C++掌握不熟悉,主要是vector部分没看过
2、没有考虑到区间问题
3、left + ((right -left) >> 1) == (left + right) /2 相当于二进制右移,这两种写法是等价的
今日收获
1、掌握二分法,区间的注意事项。
2、双指针法
day 1 | 704. 二分查找、27. 移除元素相关推荐
- day1 704.二分查找 27.移除元素
文章目录 704.二分查找 思路 代码实现 27.移除元素 思路 代码实现 704.二分查找 题目链接:704.二分查找 思路 使用二分法的前提条件: 1.有序数组 2.无重复元素 代码实现 左闭右闭 ...
- Leetcode 704.二分查找 27.移除元素 代码随想录day1
本系列目的在于跟练代码随想录,以及记录自己在数据结构与算法方面的一些学习 704.二分查找 其实之前自己在随便刷题的时候看过这道题目,就是一个纯新手的大状态,第一次听到二分查找这样的东西,然后跟着题解 ...
- 代码随想录算法训练营第一天|704二分查找 27移除元素
理论基础 1.数组是存放在连续内存空间上的相同类型数据的集合 2.数组可以方便的通过下标索引的方式获取到下标下对应的数据 3.数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要 ...
- 代码修炼Day1_LeetCode704二分查找27移除元素
代码修炼Day1_LeetCode704二分查找&27移除元素 一些数组基本知识 数组下标都是从0开始的 数组内存空间的地址是连续的 题目链接: 力扣704二分查找 二分查找思想 针对升序数组 ...
- 代码随想录Day01:数组理论基础、二分查找、移除元素
目录 数组理论基础.二分查找.移除元素 1.数组理论基础 2.Leetcode704.二分查找 方法一 左闭右闭: 方法二 左闭右开: 方法三 左开右开: 方法四 左开右闭: 3.Leetcode27 ...
- Day01.二分查找、移除元素
Day01.二分查找.移除元素 0704.二分查找 题目链接:0704.二分查找 思路:二分查找,仅对有序数组有效.每次需要数组的中间值,与目标值比较大小,如果中间值比目标值大,说明目标值位置在lef ...
- 代码随想录01 | 704二分查找和27移除元素
目录 一 .二分查找 1 二分查找 2 搜索插入位置 3 在排序数组中查找元素的第一个和最后一个位置 二.移除元素 一 .二分查找 1 二分查找 704 二分查找https://leetcode.c ...
- 【Day1】数组、704二分查找、27移除元素
[Day1]数组.704二分查找.27移除元素 数组 704 二分查找 版本一 左闭右闭 即[left, right] 版本二 左闭右开 即[left, right) 27 移除元素 暴力解法 双指针 ...
- 代码随想录算法训练营第一天 704 二分查找、27 移除元素
代码随想录算法Day1 | 704. 二分查找.27. 移除元素 Last edited time: April 5, 2023 11:27 AM 数据理论基础 数组是存放在连续内存空间上的相同类型数 ...
- Suzy找到实习了吗 Day 1 | 704. 二分查找、27. 移除元素
Suzy找到实习了吗 | 704. 二分查找.27. 移除元素 Leetcode 704:二分搜索 收获 Divide and conquer Recursive relation Python 3 ...
最新文章
- 用神经网络模拟分子:碱金属的氯化物
- android 拍照不能保存图片格式,Android 拍照后保存到手机里,在相册找不到
- nginx学习文档之一 安装nginx-Windos下安装nginx
- linux看火狐的安装目录,linux下firefox+geckodriver环境搭建
- EXCEL数据有效性—单元格筛选的改进
- mysql中查询编辑器_万能数据库查看器|Universal SQL Editor(万能SQL编辑器)下载 v1.8 官方版 - 比克尔下载...
- 怎么在国内创建谷歌账号_如何在Google相册中创建和共享协作相册
- hadoop启动cgroups,centos6.5+hadoop2.7.2
- Latex中的参考文献写法
- rabbitmq连接特别慢 一直连接超时 An unexpected connection driver error occured
- 如何实现1分钟写一个API接口
- 学英语《每日一歌》之because of you
- 微信小程序+PHP 从零写一个微信小程序
- 原西北大学校长郝克刚教授在中服PaaS云平台技术研讨会上的讲话
- python 学习分享之简单的播放音乐1(playsound)
- FCoin爆雷,大咖答主教你如何挽回损失 | 一周问答热议
- 礼品卡配合U盘,美国一公司遭受BadUSB真实攻击
- NVIDIA显卡驱动未加载问题——未完全解决
- (root) Additional property nginx is not allowed
- 白领创业做起了小龙虾的生意,如今公司日销售额达30万元