目录
题目
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
分析
方法1:双指针。左指针指向已处理数组的尾部,右指针为未处理数组的头部,若右指针指向的元素不等于val,将右指针指向的值赋给左指针指向的值,左指针向右移动一位,右指针向右移动一位。最坏情况是左右指针各遍历一次数组
方法2:优化的双指针。如果要移除的元素再数组的开头,方法一会将其余的元素均向左移动,因此,优化双指针,左指针再数组头部,右指针再数组尾部,若左指针指向的元素为val,则将右指针的元素覆盖过来,判断左指针,一直等到覆盖过来的元素不是vla,移动左指针,当左右指针从何的时候,遍历整个数组。方法二避免了需要保留元素的重复赋值操作。
代码
***python***
方法1:双指针
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
if not nums:
return 0
n = len(nums)
slow = fast = 0
while fast < n:
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
执行用时: 36 ms
内存消耗: 14.9 MB
方法2:优化双指针
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
if not nums:
return 0
n = len(nums)
left,rigth = 0,n
while left < rigth:
if nums[left] == val:
nums[left] = nums[rigth-1]
rigth -= 1
else:
left += 1
return left
执行用时: 28 ms
内存消耗: 15 MB
***cpp***
方法1:双指针
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int left = 0;
for (int right = 0;right < n; ++right){
if (nums[right] != val){
nums[left] = nums[right];
++left;
}
}
return left;
}
};
执行用时: 0 ms
内存消耗: 8.5 MB
方法2:优化双指针
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left = 0,right = nums.size();
while (left < right){
if (nums[left] == val){
nums[left] = nums[right-1];
right--;
}
else{
left++;
}
}
return left;
}
};
执行用时: 0 ms
内存消耗: 8.6 MB