记录过程
题目链接
理解题意
即原地移除 所有数值等于val的元素,返回删除后的元素数量
- 输入: 一维数组,
val - 输出:返回删除后的元素数量
- 边界条件:题目没有给出,但是应该要考虑数组为空的情况
举例验证
nums = {4,4,5,6,7,8,-1,0,3,-1},val = -1
返回 8
nums = {},val = -1
返回 0
暴力解法
不管题目的限制了
java
class Solution {
public int removeElement(int[] nums, int val) {
int[] temps = new int[nums.length];
int res = 0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=val)
temps[res++] = nums[i];
}
return res;
}
}
N是nums的长度
- 时间复杂度:O(N)
- 空间复杂度:O(N)
优化思路
暴力解法的空间复杂度太高了,数组类的题目可以尝试从以下角度去优化
- 双指针
- 哈希表
哈希表,这个我想不出来与哈希表有什么关系
双指针,这个有套路,要么是同向而行,要么是相向而行
我们来看看相向而行
思路: 把val扔到尾部
利用两个指针:left,right
- nums[left] == val
left与right指向的值互换
int t = nums[left]
nums[left] = nums[right]
nums[right] = t
right --
- nums[left] != val
left++
left可以等于right,例如就只有一个元素就是val,例如{-1},val=-1哈
所以就是
java
while(left<=right){
if(nums[left] == val){
nums[left] = nums[right];
nums[right] =val; // 可以不做,因为题目不关心right后面的
right--;// 右边界缩小
}else{
// 如果左边不是val,左指针前移
left++;
}
}
// 此时 right 指向的是最后一个有效元素的前一个位置
// 所以有效长度是 right + 1
return right + 1;
同向而行,快慢指针,记忆一下套路
java
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0; // 慢指针,指向待填充的位置
// fast 快指针,负责遍历
for (int fast = 0; fast < nums.length; fast++) {
// 如果快指针指向的值不等于 val
if (nums[fast] != val) {
// 将其值复制给慢指针位置
nums[slow] = nums[fast];
// 慢指针前进一步
slow++;
}
// 如果等于 val,快指针继续走,慢指针不动(相当于跳过该元素)
}
// 慢指针的最终位置就是新数组的长度
return slow;
}
}