算法题目笔记
数组
2.移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。。
- 暴力解法
看到这道题目的思路就是遇到值为val的数组元素,就将数组中在val后面的所有元素前移,这样就能覆盖掉val,同时不会使用额外的空间。
代码如下:
class Solution {
public int removeElement(int[] nums, int val) {
int length = nums.length; // 记录数组的初始长度
for (int i = 0; i < length; i++) {
if (nums[i] == val){ // 遇到寻找的值
for (int j = i ; j < nums.length - 1; j++) {
nums[j] = nums[j + 1]; // 从后往前依次覆盖
}
i --; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
length --; // 此时数组的大小-1
}
}
return length ;
}
}
但是毫无疑问,上述解法的时间复杂度比较高,为O(n^2),空间复杂度为O(1)。
- 双指针法
双指针法:通过一个快指针和一个满指针在同一个for循环中完成两个for循环的工作。
定义快慢指针:
快指针:寻找新数组的元素,新数组就是不含有目标元素的数组
慢指针:指向更新新数组下标的位置
代码如下:
class Solution {
public int removeElement(int[] nums, int val) {
// 快慢指针
int fastIndex ;
int slowIndex = 0;
for (fastIndex = 0; fastIndex < nums.length ; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex ++;
}
}
return slowIndex;
}
}
时间复杂度:O(n),空间复杂度:O(1)。