例题:移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
使用两个指针i和j,i用来遍历数组,j用来统计非零元素个数,每次将num[i]的值赋值给num[j],最后将j后面的元素清0即可。
1.移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路和例题一模一样,不再赘述
2. 删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
由于是排序数组,所以只需要保证当前元素和前一个元素不相等即可。同样使用双指针,不过这次统计的是不重复元素的个数,然后赋值即可。
3.删除排序数组中的重复项 II
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
这个题的思路和前面都以一样的,就是用一个指针作为新数组下标,另一个遍历。不过不同的是,这次是允许有两个元素重复。
在逻辑上,我出现了问题,因为一旦把下一个值赋值给了上一个,那岂不是下一个判断一定会重复?这怎么解决。
此时,要好好分析,变量的意义是什么。
首先i
作为遍历数组的指针,j
的作用就是统计没有发生高于两次重复的次数。当没有发生三次重复时,j++
,把i
放到j
的位置。所以,一旦发现三次重复,j
就不动。这样,由于i先判断再赋值,所以不会出现思考的问题。
不过,就不能比较和前一个了,要用一个计数的count
来统计数字出现的次数。
class Solution {
public int removeDuplicates(int[] nums) {
int count = 1;
int j = 1;
for(int i=1;i<nums.length;i++){
if(nums[i]!=nums[i-1]){
count = 1;
}else{
count++;
}
if(count<=2){
nums[j] = nums[i];
j++;
}
}
return j;
}
}