今日任务:数组理论基础,704.二分查找,27.移除元素
卡哥建议:(1)了解一下数组基础,以及数组的内存空间地址,数组也没那么简单。
(2)把 704 掌握就可以,35.搜索插入位置 和 34. 在排序数组中查找元素的第一个和最后一个位置.
重点:要熟悉 根据 左闭右开,左闭右闭 两种区间规则 写出来的二分法。
链接:代码随想录:代码随想录 (programmercarl.com)
补充:35搜索插入位置;34在排序数组中查找元素的第一个和最后一个位置;69.X的平方根;367.有效的完全平方数
代码随想录
1.数组是存放在连续内存空间上的相同类型数据的集合。
2.数组下标都是从0开始的。
3.数组的内存空间的地址是连续的。
注意事项:因为数组的内存空间地址是连续的,所以我们在删除或者增添元素时,就难免需要移动其他元素的地址。(因此数组的元素不能删除,只能覆盖。)
int arr[2][3] =
{
{0,1,2},
{3,4,5}
};
cout << &arr[0][0] << " " << &arr[0][1] << " "
<< &arr[0][2] << " " << &arr[1][0] << " "
<< &arr[1][1] << " " << &arr[1][2] << " "
<< endl;
地址一般为16进制且连续;A代表10,"ABCDEF0123456789"类推.
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文章链接:代码随想录
视频链接:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
第一想法第一次写:只想着遍历,没有时间概念,就遍历返回了;
划重点:有序数组--无重复元素--使用二分法
注意:边界条件确定好;[left,right]和[left,right)
class Solution {
public:
int search(vector& nums, int target) {
//设置区间;
int left=0;
int right=nums.size()-1;
//进行二分法算法设计
while(left<=right)
{
//设置二分中间值,注意防溢出;int向下取整
int middle=left+(right-left)/2;
//条件判断--三种情况
//target>middle,上半区间,左边界变化
if(target>nums[middle])
{
left=middle+1;//已经大于了,所以+1;
}
//target
第二种写法为边界[left,right)
class Solution {
public:
int search(vector& nums, int target) {
//设置区间;
int left=0;
//注意不能-1;否则少了数组最后一个元素
int right=nums.size();
//进行二分法算法设计
while(leftmiddle,上半区间,左边界变化
if(target>nums[middle])
{
left=middle+1;//已经大于了,所以+1;
}
//target
相关题目:35搜索插入位置;34在排序数组中查找元素的第一个和最后一个位置;69.X的平方根;367.有效的完全平方数
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文章讲解:代码随想录
视频链接:数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili
注意:要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
此为暴力解法
class Solution {
public:
int removeElement(vector& nums, int val) {
//设置数组大小
int size=nums.size();
//遍历数组删除数值val
for(int i=0;i
while与if区别:
while语句属于循环语句,在判断是,如果条件为true,则会继续判断,直到false为止,即会进行多次判断(除非一开始条件就是错的)
if语句属于条件判断语句,如果条件是true,则继续执行,为false则跳出语句不执行,只会进行单次判断。
while与if语句的最大的相同点是都有至少一步的判断。
最大的不同点是:IF语句运行完毕后,接着运行下面的语句。而While中的执行语句运行完毕后,还要进行继续判断条件是否符合循环条件,根据判断的条件,返回执行语句或继续运行下面的程序。
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
其实就是用一个快指针遍历整个数组,当找到需要的数值时,慢指针操作(此题就是慢指针重写数组)
class Solution {
public:
int removeElement(vector& nums, int val) {
//设置数组大小
int slowIndex=0;
//设置快慢指针在一个for循环里面完成移除元素
for(int fastIndex=0;fastIndex
相当于一边从头出发找到不一样的就前进,找到一样的停下替换从后面找到的不一样的,疑惑的是,最后面的一样的咋办,就消失了,确实是有这样,因为左右一起走,这样的话右边不一样的就换全部换到左边,而一样的就被抛弃了,注意要left<=right;这样就全了
class Solution {
public:
int removeElement(vector& nums, int val) {
//相向双指针法
//相当于一边从头出发找到不一样的就前进,找到一样的停下替换从后面找到的不一样的
//疑惑的是,最后面的一样的咋办,就消失了
//确实是有这样,因为左右一起走,这样的话右边不一样的就换全部换到左边,
//而一样的就被抛弃了,注意要left<=right;这样就全了
//相向双指针建立
int leftIndex=0;
int rightIndex=nums.size()-1;
//建立循环条件
while(leftIndex<=rightIndex)
{
//左边一直前进,寻找等于val的值
while(leftIndex<=rightIndex && nums[leftIndex]!=val)
{
leftIndex++;
}
//右边寻找不等于val的值,
while(leftIndex<=rightIndex && nums[rightIndex]==val)
{
rightIndex--;
}
//替换---需要添加if(leftIndex < rightIndex),防止=时,最后一个元素重复
//因为=时仍会执行,这样leftIndex就会多加一位(此时leftIndex > rightIndex),等于rightIndex或 rightIndex--的值,这样就会多算一步
if(leftIndex
相关题目:26.删除排序数组中的重复项;283.移动零;844.比较含退格的字符串;977.有序数组的平方