【Day1】数组、704二分查找、27移除元素

  • 数组
  • 704 二分查找
    • 版本一 左闭右闭 即[left, right]
    • 版本二 左闭右开 即[left, right)
  • 27 移除元素
    • 暴力解法
    • 双指针法

练习的题目来自力扣,顺序按照代码随想录进行。

数组

数组是存放在连续内存空间上的相同类型数据的集合。

  • 数组的下标都是从0开始的
  • 数组内存空间的地址是连续的(一维、二维都是连续的)
  • 数组的元素是不能删的,只能覆盖
  • 数组是随机存取的存储结构

如果使用C++的话,要注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组。
vector是顺序容器,其利用连续的内存空间来存储元素,但是其内存空间大小是能够改变的。
array是顺序容器,其也是利用连续的内存空间来存储元素,但它的内存空间是固定大小的,申请之后就无法改变。

704 二分查找

二分查找的前提是数组是有序数组,且数组中无重复元素。

因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。

写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。

题目链接:704 二分查找

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

版本一 左闭右闭 即[left, right]

[left, right] 左右两边都能取到,nums[m]不可能等于target,所以nums[m]>target,则right=m-1

// 版本一 左闭右闭即[left, right]
class Solution {public:int search(vector<int>& nums, int target) { //vector好比是一个数组int left=0;int right=nums.size()-1;    //左闭右闭,下标从0开始,最后一个数就是个数减1while (left<=right){int middle=left+((right-left)/2);  //防止溢出,等价于 (left+right)/2if(nums[middle]>target){right=middle-1;//target在左区间, middle是几个数值的中间数 数组这里是以下标看来值,因此下标-1}else if(nums[middle]<target){left=middle+1;//target在右区间}else{              //nums[middle]==targetreturn middle;}}// 未找到目标值return -1;}
};

关于下面这句代码

 int middle = left + ((right - left) / 2);  //而不用mid = (left+right)/2

原因:mid = (left + right) / 2 容易溢出!因为left+right很容易超过int范围!而mid = left + (right - left) / 2 不容易溢出,所以建议以后写二分时要用mid = left + (right - left) / 2
来源:二分查找

版本二 左闭右开 即[left, right)

[left, right) 左边值能取到右边值取不到,nums[m]可能等于target,所以nums[m]>target,则right=m

// 版本二  左闭右开即[left, right)
class Solution {public:int search(vector<int>& nums, int target) {int left=0;int right=nums.size();    //左闭右开,while (left<right){int middle=left+((right-left)>>1);  //防止溢出,(right-left)>>1相当于(right - left)/2if(nums[middle]>target){right=middle;//target在左区间,[left,middle)}else if(nums[middle]<target){left=middle+1;//target在右区间,[middle+1,right)}else{              //nums[middle]==targetreturn middle;}}// 未找到目标值return -1;}
};

下面这句代码中的 (right - left) >> 1相当于(right - left)/2

int middle = left + ((right - left) >> 1);

原因:还是担心left+right可能会超过基本类型的最大值
来源:left + ((right -left) >> 1

27 移除元素

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。

题目链接:27移除元素

题目:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

暴力解法

暴力解法是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组。
时间复杂度:O(n^2)
空间复杂度:O(1)

//暴力解法  两层for 循环
class Solution {public:int removeElement(vector<int>& nums, int val) {int size=nums.size();for(int i=0;i<size;i++){if(nums[i]==val){for(int j=i+1;j<size;j++){nums[j-1]=nums[j];   //后面的数往前移}i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位size--; // 此时数组的大小-1}}return size;}
};

双指针法

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组需要的元素 ,新数组就是不含有目标元素的数组(删除目标值后的数组)
  • 慢指针:指向更新 新数组下标的位置

快指针就是用来创建新数组的,当快指针不等于目标值(要删除的数)时,那就是我们创建的新数组需要的元素,我们要更新数组,把快指针所获取的值赋给新数组所对应的下标的位置,就是把快指针给到慢指针所在的位置,慢指针就是更新新数组的位置。快指针把值赋给慢指针后,慢指针也需要向后移动一个位置来继续更新。当快指针碰到要删除的元素值时,下面的这个for循环里面的内容就不会进行,快指针继续向后移动,慢指针还在原来的位置(这一步就是进行了移除元素)

// 时间复杂度:O(n)
// 空间复杂度:O(1)
//双向指针 快慢指针
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;  //慢指针对应的下标就是新数组中的大小}
};

【Day1】数组、704二分查找、27移除元素相关推荐

  1. day1 704.二分查找 27.移除元素

    文章目录 704.二分查找 思路 代码实现 27.移除元素 思路 代码实现 704.二分查找 题目链接:704.二分查找 思路 使用二分法的前提条件: 1.有序数组 2.无重复元素 代码实现 左闭右闭 ...

  2. Leetcode 704.二分查找 27.移除元素 代码随想录day1

    本系列目的在于跟练代码随想录,以及记录自己在数据结构与算法方面的一些学习 704.二分查找 其实之前自己在随便刷题的时候看过这道题目,就是一个纯新手的大状态,第一次听到二分查找这样的东西,然后跟着题解 ...

  3. 代码随想录算法训练营第一天|704二分查找 27移除元素

    理论基础 1.数组是存放在连续内存空间上的相同类型数据的集合 2.数组可以方便的通过下标索引的方式获取到下标下对应的数据 3.数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要 ...

  4. 代码修炼Day1_LeetCode704二分查找27移除元素

    代码修炼Day1_LeetCode704二分查找&27移除元素 一些数组基本知识 数组下标都是从0开始的 数组内存空间的地址是连续的 题目链接: 力扣704二分查找 二分查找思想 针对升序数组 ...

  5. 代码随想录Day01:数组理论基础、二分查找、移除元素

    目录 数组理论基础.二分查找.移除元素 1.数组理论基础 2.Leetcode704.二分查找 方法一 左闭右闭: 方法二 左闭右开: 方法三 左开右开: 方法四 左开右闭: 3.Leetcode27 ...

  6. Day01.二分查找、移除元素

    Day01.二分查找.移除元素 0704.二分查找 题目链接:0704.二分查找 思路:二分查找,仅对有序数组有效.每次需要数组的中间值,与目标值比较大小,如果中间值比目标值大,说明目标值位置在lef ...

  7. 代码随想录算法训练营第一天 | 数组理论基础,704. 二分查找,27. 移除元素

    今日学习的文章链接如下: 代码随想录 (programmercarl.com) 代码随想录 (programmercarl.com) 704. 二分查找 自己看到题目的第一想法 拿到题目首先想办法,一 ...

  8. 【代码随想录算法练习】| DAY01 | JavaScript | 数组理论基础,704. 二分查找,27. 移除元素

    详细解析:请看Carl老师的讲解 数组基础理论 下标从 0 开始 内存空间地址是连续的 增删元素时,会涉及其他元素地址的变动 704. 二分查找 | 点击查看力扣对应题目 二分法,也叫折半查找法,这里 ...

  9. 代码随想录算法训练营第一天 704 二分查找、27 移除元素

    代码随想录算法Day1 | 704. 二分查找.27. 移除元素 Last edited time: April 5, 2023 11:27 AM 数据理论基础 数组是存放在连续内存空间上的相同类型数 ...

最新文章

  1. 正确使用STL-MAP中Erase函数
  2. 机器学习面试题集 - 详解四种交叉验证方法
  3. Nature科学报告:根据大脑思维意图来生成对应匹配的图像
  4. Spring-AOP 自动创建代理之DefaultAdvisorAutoProxyCreator
  5. 赠票福利 | 2019,GMIS归来!杨强、吴恩达等全球重磅嘉宾共话数据智能
  6. 分布式事务:RocketMQ实现分布式事务原理
  7. php必须掌握的库,PHP初學者必須掌握的10個知識點
  8. ccBPM典型的树形表单和多表头表单的流程示例
  9. spring框架mvc框架_Spring的MVC测试框架入门–第1部分
  10. python获取局域网在线主机_pythond的icmp广播报获取局域网主机IP
  11. ffmpeg实战教程(七)Android CMake avi解码后SurfaceView显示
  12. 12306抢票脚本 python_春运抢票靠加速包?试试这个 Python 开源项目吧
  13. javasript深度拷贝
  14. opencv3计算机视觉+Python(四)
  15. 黑马程序员Python教程——Python从入门到精通教程
  16. 黑客帝国中的代码雨写法
  17. C语言版数据结构计算顺序表中X的个数,设计算法。数据结构课后习题,定义顺序表,查找顺序表中X元素的个数。
  18. Android netd和Framework以及netd和kernel之间的通信
  19. 阿里员工内部常用免费工具包
  20. 键盘录入 写入文件 quit时 结束

热门文章

  1. 阿里云域名购买至备案流程
  2. GPRS模块 测试项目
  3. 【漏洞复现】永恒之蓝 MS17-010 远程溢出漏洞(CVE-2017-0143)
  4. MYSQL修改数据库密码
  5. 图解Linux命令之--modprobe命令
  6. ENSP华为模拟器:基础命令及简写
  7. ARDUINO传感器专题介绍(2)
  8. java类图与代码实例
  9. 关系模式的完整性约束
  10. 哈希表、红黑树、B树、B+树基础