目录
二分法的主流思路有两种:“[ ]左闭右闭”,和[ )左闭右开,这两个说话,类似于数学上的区间概念,区别在于右侧如何处理。
一: 数组的理论内容
数组在内存中的存储方式是:连续存储,下标从0开始,优点是:方便查找元素,直接利用数组下标来获取元素,不足之处:不方便插入和删除元素。数组中的元素不能被彻底删除,只能通过移动元素来覆盖,以及在插入元素的时候,首先将待插入元素的位置~数组的末尾从后向前移动。这样做的目的是:保证数组元素发生变化时,依然符合连续存储的特点。
二:704 二分查找的简单入门
题目要求:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
解题思路:
题目中,给定的是:有序数组, 查找某个特定的元素,这个时候考虑二分法。
二分法的主流思路有两种:“[ ]左闭右闭”,和[ )左闭右开,这两个说话,类似于数学上的区间概念,区别在于右侧如何处理。
体现在代码上的区别如下:
[ ] 左闭右闭:
- 最开始的right=数组长度减1;
- 以及在查找过程中右指针=mid-1;
[ ) 左闭右开:
- 最开始的数组长度=length;
- 以及在查找的过程中:右指针=mid;
[ 左闭右闭]代码如下:
个人收获:
- 我之前求mid的下标: int mid =(left+right)/2,今天看群友的解释,理解了这种做法不安全,当target的下标接近数组尾部,right数值很大,以及在查找后期时,left的值也会很大,相加会超过int的取值范围,存在越界的可能,安全的做法是:int mid=(right-left)/2+left;
- while(left<right)还是while(ledt<=right)?当我拿不定注意的时候,我两个都尝试了一下,其中while(left<right)时,系统报错,给出的示例是:nums: [5].target=5,学会了,我自己当时想到的是:在一个数组中,如果left和right同时指向一个元素,此时也要判断一下,但是不如系统的示例如此的简单、直接。
- 熟练度,这个题目自己在很早就写过了,今天再看的时候,基本上是想了几分钟,就能写出草稿。
27. 移除元素
题目要求:给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
解题思路:
要求原地移除所有等于val的元素,反过来的一个思路是:我只需要保存所有不等于val的元素
具体做法:
需要有两个“哨兵”,一个哨兵i的作用是:来遍历原数组中的所有元素,找到不等于val的所有元素,另一个哨兵j从0开始保存哨兵i找到的不等于 val的元素。
核心代码:
if (nums!=val)
{
nums[i]=nums[j];
i++;
}
完整代码如下:
个人收获:
- 这个题目很早之前也写过,今天用了很快的时间写出了草稿版。说明自己之前的掌握还是不错的。
- 因为写博客的原因,让自己的思路更加的成熟了,坚持写下去,锻炼自己的写作技能。