给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。 由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。 将最终结果插入 nums 的前 k 个位置后返回 k 。 不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
方法一:排队找空位
定义一个变量用来记录val出现的次数,判断数组中的值是否与val相等 如果相等计数器count进行++操作,如果不等,就将不相等的数字覆盖到val上,最后输出nums.length - count即为数组的新长度。
public int removeDuplicates(int[] nums, int val) {
//首先先对入参进行判断
if (nums == null || nums.length < 2) {
return 0;
}
//排队找空位法
//定义一个变量用来记录val出现的次数
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == val) {
count++;
} else {
//更新操作 将第i个位置上不是val的值放在val上 覆盖val
nums[i - count] = nums[i];
}
}
//返回的nums.length - count即为数组的新长度
return nums.length - count;
}
方法二:双指针法
定义一个头指针i 一个尾指针j,判断i位置上的数是否与val相等,如果相等交换i与j 位置上的数,i进行--操作后, 循环中又执行了i++操作 就可以判断交换后位置的元素是否为val,最后返回j+1即为数组的新长度。
public int removeDuplicates(int[] nums, int val) {
//首先先对入参进行判断
if (nums == null || nums.length < 2) {
return 0;
}
//双指针法
//定义一个头指针i 一个尾指针j
int j = nums.length - 1;
for ( int i = 0; i <= j; i++) {
if (nums[i] == val) {
//交换i和j的位置 i--操作 重新判断交换过后的i
// i=1 j=2
nums[i] = nums[i] ^ nums[j];//nums[i]=1^2
//nums[j]=1^2^2
nums[j] = nums[i] ^nums[j];
//nums[i]=1^2^1
nums[i] = nums[i] ^ nums[j];
//i--后 循环中又执行了i++操作 就可以判断交换后位置的元素是否为val
i--;
//j-- j位置上已经存放了val 所以j进行--操作 方便下一次交换
j--;
}
}
//数组的下标是从0开始的 所以最后要进行+1操作
return j + 1;
}