本文来自LeetCode领扣 网址:http://mp.weixin.qq.com/s/b2vbzgrObeDa5xd8j5wJRg
为什么要写这个问题,觉得看完这种方法之后,觉得特别的巧妙,打破了我固有的思维。
题目:给定一个数组nums和一个值var,你需要将这个数组中与var相等的数移除数组,返回移除后数组的长度。
要求:不要使用额外的数组空间,意思是空间复杂度为O(1),而且必须在原地修改输入数组。然后
数组的顺序可以改变。
例子:数组nums=3 2 2 3 ;var = 3;后来返回长度2,并且数组中两个元素都为2
数组nums=0 1 2 2 3 0 4 2;var = 2后来返回长度为5,并且前五个元素为0 1 3 0 4,这五个
程序为任意顺序,你不需要考虑数组中超出新长度后面的元素
精华觉得在:对这个数组进行内部操作,引用了指针的原理对其进行移动。
方法一:双指针(我们保留两个指针i和j,其中i为慢指针,j为快指针)
代码:
package mypackage;
public class YiChuShuZu {
public int caoZuo(int[] nums,int var) {
int i = 0;
for(int j = 0; j < nums.length ;j ++) {
if(nums[j] != var) {
nums[i] = nums[j];
i++;
}
}
return i;
}
}
分析:时间复杂度:O(n),假设数组总共有n 个元素,i和j至少遍历2n步
空间复杂度:O(1)
方法二:双指针(当要删除元素时,将数组的最后一位移到这个删除的位置同时数组长度n要减1)
思路:现在考虑数组包含要删的元素很少,这样的话就造成了要遍历一些不必要删除的元素。
如:nums={1,2,3,5,4} var=4,第一个程序就多遍历了1,2,3,5,进行了.不必要的操作。
如:nums = {4,1 ,2 ,3 ,5} var = 4,那就没必要将1,2,3,5都左移一位,因为题中的数组元素的顺序可以更改。
package mypackage;
public class YiChuShuZu {
public int caoZuo(int[] nums,int var) {
int i = 0;
int n = nums.length;
while(i < n) {
if(nums[i] == var) {
nums[i] = nums[n-1];
n--;
}
else {
i++;
}
}
return n;
}
}