代码随想录算法训练营第一天 LeetCode 704 二分查找、LeetCode 27 移除元素(暴力和双指针)

    return -1;
}

}


因为是左闭右闭的区间,即[L,R]。在while循环中,我们需要考虑的是数组区间一直是合法的。所以,在条件上我们需要思考到底是**left<right**还是**left<=right**。举个例子,区间[1,1]是一个合法区间,表示只有1一个元素,因此在左闭右闭中,left<=right。而在下面给right和left重新赋值的语句,因为已经判定middle大于或小于target,我们可以在新数组中将middle出去,因此赋值应该是middle+1或middle-1。


#### 左闭右开



class Solution {
public int search(int[] nums, int target) {
int left=0;
int right=nums.length;
while (left<right){
int middle = (left+right)/2;
if (nums[middle] > target){
right = middle;
}
else if (nums[middle] < target){
left = middle+1;
}
else {
return middle;
}
}
return -1;
}
}


左闭右开的写法中,需要注意的是right赋值的不同(因为右边取不到所以需要等于nums.length来囊括所有元素)。其次是while循环条件的不同,同样举个例子,[1,1)这个数组是不合法的,因此在左闭右开中left不能等于right。最后是赋值右边界的不同,因为无法取到最右边,因此需要赋值为middle来囊括所有可能元素。而因为左边界可以取到,因此左边界赋值相同。


**低级错误:middle是需要不断改变的,因此要放在循环里。(很低级,大佬轻喷。)**


## LeetCode 27 移除元素


题目链接:[. - 力扣(LeetCode)]( )


首先,我们先思考一下怎么移除数组。数组,是一个**连续**的拥有相同类型的若干元素的集合。既然是连续的,我们无法直接删除某一元素,而是需要将其后面的元素往前覆盖一格来达到删除该元素的效果。而在执行完这一过程后,整个数组大小其实并没有变,只不过不同库函数对返回值进行了包装才达到了大小缩减的效果。(详细见讲解视频前四分钟理论基础:[数组中移除元素并不容易! | LeetCode:27. 移除元素\_哔哩哔哩\_bilibili]( ))


因此,来达成这一效果,可以使用两个for循环或一个for循环(双指针)来解决。


#### 暴力解法


暴力解法也即使用两个for循环来解决问题。像我上面说的,在数组中删除元素相当于将其后面的元素往前覆盖来达成效果。因此实现思路其实很简单,即只要遇到需要删除的元素就把之后的元素往前覆盖并且size-1,直到找不到需要删除的元素为止。



class Solution {
public int removeElement(int[] nums, int val) {
int size = nums.length;
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–;
size–;
}
}
return size;
}
}


需要注意的是,在覆盖完后面的元素,即第二个for循环完结后,需要把当前的i-1。原因是因为,我们把后面的元素全部提前覆盖了,因此当前的i位置是它后面的元素,也是我们还没有检查的元素。而如果我们没有对i进行任何操作,那么下一步我们将到i+1的位置,也即是本来i+2位置的元素,而跳过了原本i+1位置的元素没有被检查。因此如果需要删除的元素连续出现就会出现问题。


**而在写上述代码的时候我还犯了一个很低级的错误。我把i--和size--的代码放在了if语句之外,因此出现了空元素的问题。对于i的操作和size减少的操作应该在碰到需要删除的元素时,所以应该在if语句里面。(很低级,大佬轻喷。)**


#### 双指针方法


上述两个for循环的方法的时间复杂度为O(n^2),而我们可以使用双指针,即一个for循环,时间复杂度为O(n)的方法来解决问题。


思路是,分为一个快指针和慢指针。慢指针是需要替换为新元素的位置,快指针是新元素。那么也就是说,我们考虑的是删除元素之外的元素,也就是说重组剩下的元素。例如,一个数组为






### JavaScript 和 ES6



在这个过程你会发现,有很多 JS 知识点你并不能更好的理解为什么这么设计,以及这样设计的好处是什么,这就逼着让你去学习这单个知识点的来龙去脉,去哪学?第一,书籍,我知道你不喜欢看,我最近通过刷大厂面试题整理了一份前端核心知识笔记,比较书籍更精简,一句废话都没有,这份笔记也让我通过跳槽从8k涨成20k。

![JavaScript部分截图](https://img-blog.csdnimg.cn/img_convert/cac778dc45492a41e2f3e7cd6b0134e5.png)

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值