移除数组中的指定值
Input:数组nums,需要移除的元素val
Output:原数组nums以及移除val后的数组长度
这是LeetCode上难度为简单的题,最近做的时候,首先想的方法就是,判断当前有多少个连续的值均为val,然后把后面的元素全部前移,如下所示。
public int removeElement(int[] nums, int val) {
//首先判断数组是否为空
if(nums == null || nums.length == 0) return 0;
int count = 0;
for(int i = 0;i<nums.length;i++){
if(nums[i] == val){
int bias = 0;
for(int j = i;j<nums.length;j++){
if(nums[j] != val) break;
bias++;
}
shiftLeft(nums, i, bias, val);
}
}
//此时数组后部分全为元素val,需要遍历一次然后计数
for(;count<nums.length;count++){
if(nums[count] == val) break;
}
return count;
}
/* 将start+bias开始的值全部前移bias个位置*/
private void shiftLeft(int[] nums, int start, int bias, int val){
for(int i = start+bias;i<nums.length;i++){
nums[i-bias] = nums[i];
//表明该位置的值无效,所以重新赋值为val
nums[i] = val;
}
}
然后一提交发现自己10个月前已经做过了! = _ =,而且当时使用的是一个双指针,代码更加通俗易懂,和官方解答是一样的。平常还是得多学习总结,继续努力才行,唉。。。
(仅遍历一次,时间复杂度为O(n),空间复杂度为O(1))
public int removeElement(int[] nums, int val) {
if(nums == null || nums.length == 0) return 0;
//记录当前元素个数
int count = 0;
for(int i = count;i<nums.length;i++){
if(nums[i] != val){
nums[count++] = nums[i];
}
}
return count;
}
然后是又刷了一道类似的题,需要移除数组中重复的元素,也就是每个元素只保留一次
Input:数组nums
Output:原数组nums以及移除val后的数组长度
仍然是双指针的思路,相比于前一题,这次不是往后移一个位置就行了,而是平移至另一个不等的元素,所以使用了一个while循环代替了原来的i++。
public int removeDuplicates(int[] nums) {
//count记录当前元素个数
int count = 0;
for(int i = count;i<nums.length;){
int val = nums[i];
nums[count++] = val;
while(i < nums.length){
if(nums[i] != val){
break;
}
i++;
}
}
return count;
}