LeetCode题解:移除元素
2022-03-06 本文已影响0人
搬码人
题目描述
给你一个数组nums和一个值val,你需要原地删除所有值等于val的元素,并返回删除后数组的新长度。
不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
系统调用过程
int len = removeElement(nums, val);
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
方法思路
使用双指针left和right,right率先遍历,当num[right]与val值相等时,left不移动,right继续移动。直到right遍历完整个数组,数组前left个元素就是删除val后的结果。
class Solution {
public int removeElement(int[] nums, int val) {
int n = nums.length;
int left = 0;
for(int right=0;right<n;right++){
if(nums[right]!=val){
nums[left] = nums[right];
left++;
}
}
return left;
}
}
复杂度分析
- 时间复杂度:O(n),其中n为序列的长度。我们只需要遍历该序列至多两次。
- 空间复杂度:O(1),我们只需要常数的空间保存若干变量。
优化方案
同样是使用双指针,不过这次两个指针分别起始在数组最左边与最右边。
核心思想就是将需要删除的元素与最后的几位元素进行交换。
好处:这样的方法两个指针在最坏的情况下合起来只遍历了数组一次。与前一方法不同的是,方法二避免了需要保留的元素的重复赋值操作。
class Solution {
public int removeElement(int[] nums, int val) {
int right = nums.length;
int left = 0;
while(left<right){
if(nums[left]==val){
nums[left] = nums[right-1];
right--;
}else{
left++;
}
}
return left;
}
}
复杂度分析
- 时间复杂度:O(n),其中n为序列的长度。我们只需要遍历该序列至多一次。
- 空间复杂度:O(1),我们只需要常数的空间保存若干变量。