LeetCode704 二分查找
题目链接:704:二分查找
题目描述:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
思路:要用二分法求解,采用两种区间进行解决,第一种【a,b】,第二种【a,b),即左闭右闭和,左闭右开。
我个人理解
二分法:
①先将给定的区间分成左区间和右区间两个区间即给出left,right,middle。正常来说,middle = (left+right)/2可能出现越界情况,但在本题中不用担心。Note :middle = left +((right - left)>> 1)是我今天新学到的写法,a >> b 相当于,a除以2的b次幂。
②然后在循环遍历的时候比较middle 和 target的大小关系:
1.middle >target,说明target在初始分好的左区间,此时需要更改右边界
2.middle< target,说明target在初始分好的右区间,此时需要更改左边界
3.middle = target,即返回middle这个索引
③若进行了②后仍然没有对应的索引,即返回-1
④为了避免多余的循环操作,我们在最开始时要排除掉 target在给定的边界外的情况,即target < nums[left] || target > nums[right]
故最后的解题顺序即为,④->①->②->③
Note:
对于②中的循环,则分为用【a,b】还是【a,b)
当使用【a,b】时,为左闭右闭区间:初始的循环条件为left <= right; 当target<middle时,即右边界要发生变化时,右边界变为middle-1,即right = middle - 1;
当使用【a,b)时,为左闭右开区间:初始循环条件为left < right; 当target<middle时,即右边界要发生变化时,右边界变为middle,即rigt = middle;
下面两图分别为【a,b】,【a,b)的代码(java版本)
LeetCode27 移除元素
题目链接:LeetCode27:移除元素
题目描述:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路:因为数组是个数据类型相同的数据的连续集合,故对于数组中元素的删除,并不是简单的将元素删掉,而是实现元素的覆盖。即将想要删去的元素的位置覆盖上新的元素。
两种方法:方法一:暴力求解
方法二:快慢指针(同向指针,双指针的一种)
方法一:暴力求解
①遍历给定集合
②当遍历到nums【i】= val 时,将之后的元素均向前移一位,即j = i+1;nums[j-1] = nums[j];
③做完后发现,原来i位置的元素被覆盖掉变成了新的元素,此时如果i不进行改变的话,下次循环的时候,i变成了i+1,但问题是现在i位置的元素还未与val比较,故当nums【i】 = val时,i--;同时数组长度也变小了一个 故size--;
④返回size
方法二:快慢指针
①定义慢指针
②用快指针作为索引来遍历数组
③当nums【fastIndex】!= val,将快指针对应的元素值传递到慢指针对应的数组中,即nums【slowIndex】= nums【fastIndex】,并且slowIndex++。当nums【fastIndex】== val,不进行任何操作,相当于跳过了该元素,快指针继续前进,慢指针保持不变。
④最后,返回slowIndex即为新数组的长度。
下面两图分别为暴力求解和快慢指针的代码(java版本):
总结:
①求解平均值可以用a >> b,b = 1,即a除以,2的b次幂
②用二分法时,初始边界的=号有无以及在变换右边界时middle是否-1要注意,根据选择的合法区间不同加以调整。
③对于删除数组中的元素,实际上是在实现元素的覆盖而不是单纯删除某个元素
④双指针方法相对来说更为简单一些,效率也高一些。
⑤在进行二分法求某个数时,我用了递归方法,发现了很多小问题,自己忘写return,在递归调用的时候可能把递归调用函数写错
⑥在同一个类中在一个方法中想调用另一个方法,声明时最好用private修饰,虽然在704的题解中声明方法也可以用static 但是没必要。
⑦>>的优先级小于+,故在用++的时候,要注意用括号将其括起来以免出现问题。
⑧本人是个小白,今天刷了两道题。二分法,暴力法,双指针法都是先看的视频讲解然后AC的,其实就是基本的复现,写博客是个复习的过程,希望大家多多提建议,谢谢!