代码随想录第一天
创始人
2024-03-24 11:34:14
0

专题:数组

题目:二分查找

题目要求

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

题目理解:

因为题目满足 有序数组 并且 无重复元素 两个特点,所以可以对他使用二分查找。

如果不是有序数组不能使用二分查找;

如果数组有重复元素,返回的下标可能就不唯一了,所以也不能使用二分查找;

 大体思想

        用左下标left指向数组的第一个元素 ,右下标right指向数组的最后一个元素。在左下标 小于 右小标的前提下,循环进行下面的操作。

        取当前左下标 和 右下标 的中间下标对应的值 和 目标值比较,如果目标值小于中间下标对应的值,那么说明目标值在当前左右下标区间的左半部分,此时我们更新右下标,让右下标指向中间下标。然后左右下标区间就缩小了一半,下一次查找的范围也缩小了一半。

        取当前左下标 和 右下标 的中间下标的值 和 目标值比较,如果目标值大于中间下标值,那么说明目标值在当前左右下标区间的右半部分,此时我们更新左下标,让左下标指向中间下标。然后左右下标区间就缩小了一半,下一次查找的范围也缩小了一半。

        取当前左下标 和 右下标 的中间下标的值 和 目标值比较,如果目标值等于中间下标值,那么找到了目标值,直接返回中间下标。

        如果直到 左右下标不满足条件,退出循环。那说明数组中没有目标值,返回-1;

细节注意

左闭右闭:nums.size()求出的是数组的有效元素的个数。而根据数组的特性,元素下标从0开始,即第一个元素的下标是0,第二个元素的下标是1...最后一个有效元素的下标是 nums.size() -1,那么nums.size()对应的元素,就是数组后面的第一个无效元素。

         所以左闭右闭要求:左下标从第一个元素开始 left = 0;右下标指向最后一个有效元素 right = nums.size()-1; 由于左下标右下标指向的都是有效元素,所以在while循环时,条件为(left <= right);

         在更新左边界的时候,由于原来的中间指针指向的元素,已经参加了比较,所以下一个比较可以直接越过它。并且不管是左下标指向中间下标的后一个元素,还是右下标指向中间下标的前一个元素,左右下标都可以拿到这个值,参与到这次的循环比较中来。不会遗漏。所以,更新左下标的时候 left = mid+1; 更新右下标的时候 right = mid -1; 

 左闭右开:nums.size()求出的是数组的有效元素的个数。而根据数组的特性,元素下标从0开始,即第一个元素的下标是0,第二个元素的下标是1...最后一个有效元素的下标是 nums.size() -1,那么nums.size()对应的元素,就是数组后的第一个无效元素。

         所以左闭右开要求:左下标从第一个元素开始 left = 0;右下标指向数组后第一个无效元素 right = nums.size(); 由于右下标指向的是无效元素,所以在while循环时,不能取等于条件。 写为:while(left < right);

         在更新左边界的时候,由于原来的中间指针指向的元素,已经参加了比较,所以下一个比较可以直接越过它。让左下标直接指向中间下标的后一个位置的下标。但是更新右下标时,因为右下标指向的空间不能访问,所以此时,就不能让右下标指向中间下标的前一个,如果指向中间下标的前一个,那么中间下标的前一个的元素,就不能参与到下一个次循环比较当中,就会造成数据丢失。所以,更新左下标的时候 left = mid+1; 更新右下标的时候 right = mid; 

代码实现: 

 

 题目:移除元素

题目要求

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

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

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

题目理解: 

数组,原地移除所有数值等于val的值,返回数组新长度。 不能使用新空间,只能在原来的数组上进行操作,根据数组的特性,移除元素,不能删除而是依靠覆盖的方式。可以采用暴力移除法,或者快慢指针法去实现。

大体思想 

暴力循环法:第一层for循环,遍历数组。一旦发现当前元素等于val,那么就从这个元素处,再加一次for循环,把后面的元素都往前依次移动一个位置,覆盖当前的这个值等于val的元素。这样大循环完成,那么数组中值等于val的元素都会被移除。

细节注意

暴力循环法,小循环每执行一次,覆盖一个元素,控制访问数组大小的size就要减1.还有就是我们要人为的给大的for循环的循环变量减1.因为后面的元素都往前移动了一位。如果让大循环的变量直接走的话,会把本来下次应该访问的元素,结果因为后面的元素全部往前移一位,导致错过访问。所以每次小循环结束,我们要人为的给大循环的循环变量-1;

代码实现

为啥不正确???

这是因为,我们没有控制访问数组元素的大小。

知识点补充:数组无论你是前移动数组元素,还是后移动数组元素。被移动那个数组元素还存在,并且那个数组元素的值也不会改变。只是其他元素的值被赋值改变了。并且数组的大小也没有改变。nums.size()还是和原来一样。 

例如:数组[3,2,2,3],移除val=3的元素。

      大循环是for(i = 0; i < 4; i++)  然后经过第一个大循环就会变成[2,2,3,3],然后i--.又变成了for(i = 0; i < 4; i++);现在遇到[2,2]之后,变成for(i = 2; i < 4; i++);遇到了nums[2] = val;然后把后面的3往前赋值一个之后得到[2,2,3,3].此时i- - 又回到了for(i = 2; i < 4; i++);又遇到了nums[2] = val;然后又是一直循环。就会出现超时现象。

 我们要控制的,不是数组真正的大小nums.size(),而是去控制遍历数组的大小size。

所以使用一个size先记录下原来数组的大小,然后在移除的时候通过改变size的大小,来控制访问数组的大小。

例如:数组[3,2,2,3],移除val=3的元素。

      size= 4;大循环是for(i = 0; i < 4; i++)  然后经过第一个大循环就会变成[2,2,3,3], 此时size= 3; 然后i--.又变成了for(i = 0; i < 3; i++);现在遇到[2,2]之后,变成for(i = 2; i < 3; i++);遇到了nums[2] = val; i--,size--; size=2; i=2; 现在for(i = 2; i < 2;i++)退出循环了。数组的大小size就是2。

代码实现

快慢指针法:因为可以通过下标访问数组元素,所以我们可以使用两个下标,fast,slow。让fast先走,slow跟在fast后面。fast遍历数组,如果fast当前指向的元素不等于val,那么将fast指向的元素赋给slow,并且slow往下走一步。如果fast指向的元素等于val,那么啥也不干,fast继续执行循环。这样fast的循环完成之后,slow就是新数组的元素个数,并且当前数组的前slow个,就是要得到的数组。

细节注意

赋值是注意slow是先赋值后++。即 nums[slow++] = nums[fast];

代码实现 

学到的知识:深刻理解了数组元素的移动,以及数组元素的下标访问。

标准:根据自己的理解,独立写出来,并且一把运行通过。

否则:等于没学习!!!

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...