移除元素
题目:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度;不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组;元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素
题目链接:力扣
思想
方法一
暴力求解:遍历整个数组,遇到某一个元素等于val就从该元素的后一个元素开始遍历后面的元素,把后面的数组元素往前移动一个位置:
public int removeElement(int[] nums, int val) {
int i = 0;
int j = 0;
int size = nums.length;
for(i = 0;i < size;i++) {
if(nums[i] == val) {
for(j = i + 1;j < size;j++) {
nums[j - 1] = nums[j];
}
i--;
size--;
}
}
return size;
}
注意:因为最后返回的是size,所以每找到一个val并进行元素移动之后都需要让size--
方法二
计数方式:使用计数的方式(定义一个count变量),对数组进行遍历,如果元素等于val就让count++,如果数组元素不等于val就让该数组元素往前移动下标-count个单位,最后返回原数组的长度-count的个数:
public int removeElement(int[] nums, int val) {
int count = 0;
for(int i = 0;i < nums.length;i++) {
if(nums[i] == val) {
count++;
} else {
nums[i-count] = nums[i];
}
}
return nums.length - count;
}
方法三
双指针法:定义两个指针分别为fast和slow,fast指针用来遍历数组,slow指针对应的是新数组,fast指针所对应的数组元素如果步等于val的话就将fast所对应的元素赋值给slow并且让slow++,如果不等于val则不进行任何操作并继续遍历原数组,最终slow指针落在了新数组的最后一个元素+1处,所以返回的数组的长度刚好等于slow:
public int removeElement(int[] nums, int val) {
int slow = 0;
int fast = 0;
for(fast = 0;fast <nums.length;fast++) {
if(nums[fast] != val) {
nums[slow++] = nums[fast];
}
}
return slow;
}
总结
对于数组进行删除的操作要善于使用双指针的解法,定义两个指针分别为fast和slow,fast一般用来对数组进行遍历,slow指针一般对应修改过后的新的数组,此时对于满足条件的数组元素只需要将fast对应的元素赋值给slow并对slow进行++操作即可!