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

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的,其实就是基本的复现,写博客是个复习的过程,希望大家多多提建议,谢谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
第二十二天的算法训练主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值