题目描述

1.撸起袖子就是干!
1.1代码
public int myRemoveElement(int[] nums, int val) {
int k = 0, i= 0, j=0;
while(j < nums.length){
if(nums[j] != val){
//这里临时变量多余了,不用temp,nums[i] = nums[j]即可,i指向的要么是初始位置,这时候i和j相同,没关系。此外i指向的都是等于j的位置或out of index
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
//这里的K多余了,完全可以用i替代
k++;
i++;
}
j++;
}
return k;
}
1.2报错
没报错,AC了
2.题解
2.1方法一:双指针

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)。我们只需要常数的空间保存若干变量。
2.2方法二:优化双指针

class Solution {
public int removeElement(int[] nums, int val) {
int left = 0;
int right = nums.length;
while (left < right) {
if (nums[left] == val) {
nums[left] = nums[right - 1];
right--;
} else {
left++;
}
}
return left;
}
}
复杂度分析
-
时间复杂度:O(n),其中 n 为序列的长度。我们只需要遍历该序列至多一次。
-
空间复杂度:O(1)。我们只需要常数的空间保存若干变量。
3.二周目挑战BOSS
public int fixMyRemoveElement(int[] nums, int val) {
int i= 0, j=0;
while(j < nums.length){
if(nums[j] != val){
nums[i] = nums[j];
i++;
}
j++;
}
return i;
}
当然也是AC了,省了很多不必要的变量
4.程序员の沉淀
方法二避免了需要保留的元素的重复赋值操作
这个优化在序列中 val 元素的数量较少时非常有效。它的优化是减少了赋值的操作(读、写内存),当nums非常大时,运行时间将会看到明显区别
但我觉得这个解释比较扯淡,这么说方法1在val元素数量比较多时也非常有效呢!
949



被折叠的 条评论
为什么被折叠?



