给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
public class 删除有序数组中的重复项 {
public static void main(String[] args) {
int[] nums = new int[]{0, 1, 3, 3, 4, 4, 5, 6, 6, 8};
// int[] numresult = baoliDeal(nums);
// System.out.println("数组长度为:" + numresult.length);
// for (int i = 0; i < numresult.length; i++) {
// System.out.print(numresult[i] + " ");
// }
int num = removeDuplicates(nums);
}
/**
* 可以实现功能,但是不满足要求:不使用额外空间,并且 O(1) 时间
*/
public static int[] baoliDeal(int[] nums) {
int length = nums.length;
// 使用 LinkedHashSet 去重并且保证顺序不变;
Set<Integer> set = new LinkedHashSet<>();
for (int i = 0; i < length; i++) {
set.add(nums[i]);
}
//去重后的长度作为初始化的数组长度
int[] numresult = new int[set.size()];
//再将 LinkedHashSet 循环到新数组中
Iterator iterator = set.iterator();
int i = 0;
while (iterator.hasNext()) {
numresult[i] = (int) iterator.next();
i++;
}
return numresult;
}
public static int removeDuplicates(int[] nums) {
int length = nums.length;
int start = 0;
int end = 1;
while (end < length) {
//不相等就赋值,并且两个指针都往后移动一步
if (nums[start] != nums[end]) {
nums[++start] = nums[end];
}
//相等就直接后移第二个指针
end++;
}
/**
* 打印去重后的排序数组
*/
for (int j = 0; j < start + 1; j++) {
System.out.print(nums[j] + " ");
}
//只能是 start + 1 ;不能是 end ,end就是全部的数组了
return start + 1;
}
}
两种实现方式:
1.首先想到去重的并且是 Java 自带的工具类 Set 但是 Set 无序;所以使用 LinkedHashSet 保证顺序且去重,然后将 LinkedHashSet 再遍历到数组中即可。但是不满足要求
2.双指针实现,完全满足要求
while (end < length) {
if (nums[start] != nums[end]) {
if(end-start>1){ //当没有重复元素的时候,直接对比跳过,不用复制一遍(如果数组本身就满足要求,就不用复制一遍数组)
nums[start+1] = nums[end];
}
start++;
}
end++;
}