1.移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
2.解题思路
参考上一题,有些相像,所以双“指针”是可以确定的
https://blog.csdn.net/baidu_35108799/article/details/109163113
上一题是与数组内的元素进行对比,这一题是数组外的,会简单一点。
一个定海神针t总是指向新数组的结尾。然后向后查找,找到需要删除的元素了就找别的元素替换就行了,因为不要求顺序,所以为了更快一点,另一个指针i从后往前遍历,两个“指针”向中间汇聚,运行时间更快
class Solution {
public int removeElement(int[] nums, int val) {
//错误1
if(nums.length==0)
return 0;
int t=0;
int i=nums.length-1;
while(i>t){
if(nums[t]==val){
if(nums[i]!=val){
nums[t]=nums[i];
t++;
i--;
}
else i--;
}
else t++;
}
//错误2
if(i>=t)
return nums[t]==val?t:++t;
else return ++i;
}
}
运行结果比较理想
3.遇到的问题
我提交了两次都出错了,因为边界问题
首先是代码中标注的错误1,没有判断是不是空串,执行错误
第二个错误是代码标注的错误2.因为i和t是向中间汇聚,他们相遇的时候有两种情况,
一种是t==i,一种是i<t
t==i的时候就不进入循环判断了,但我们不确定nums[i]是不是等于val。所以最后要判断一下
i<t这个情况有个案例,[4,5],val=4。 这个情况我没有考虑,应该在结果处再判断一下的