1. 官网链接:
. - 力扣(LeetCode)
2. 题目描述:
给你一个 非严格递增排列 的数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums
中唯一元素的个数。考虑
nums
的唯一元素的数量为k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。- 返回
k
。判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组 int[] expectedNums = [...]; // 长度正确的期望答案 int k = removeDuplicates(nums); // 调用 assert k == expectedNums.length; for (int i = 0; i < k; i++) { assert nums[i] == expectedNums[i]; }如果所有断言都通过,那么您的题解将被 通过。
3. 我:
package com.nami.algorithm.study.array;
/**
* 描述: 删除有序数组中的重复项
*
* @Author: lbc
* @Date: 2024-03-05 8:00
* @email: 594599620@qq.com
* @Description: keep coding
*/
public class DelRepeatElementOfArray {
/**
* 思路: 首先想到的是冒泡算法
* 两层循环。第二层判断是否相等,如果第一个就不相等就退出第二层循环
* 相等就置空
* 最终输出非空长度。。
* 但是根据leetcode 的时间,空间复杂度要求, 肯定没过关! ==!
* 此处只是输出下,怎么想的,
* 这个问题的两个想法:
* 如何高效比较并删除,删除后如何放值
* 以下代码只是将上述两个行为分开了
* 此方法并没有完成题目时间,空间复杂度要求!
*
* @param array
*/
public static int removeRepeatNum(Integer[] array) {
if (array.length == 1) {
return 1;
}
if (array.length == 0) {
return 0;
}
System.out.println("开始前长度:" + array.length);
for (int i = 0; i < array.length; i++) {
Integer first = array[i];
if (first == null) {
continue;
}
for (int j = i + 1; j < array.length; j++) {
if (!first.equals(array[j])) {
break;
}
if (first.equals(array[j])) {
array[j] = null;
}
}
}
int size = 0;
for (Integer integer : array) {
if (integer == null) {
continue;
}
size++;
}
int j = 0;
// leetcode 原题是不让用新数组,或其他数据结构的。这只是第一次思路 先得出结果,再优化
Integer[] newArray = new Integer[size];
for (Integer integer : array) {
if (integer != null) {
newArray[j] = integer;
j++;
}
}
array = newArray;
for (Integer integer : array) {
System.out.print(integer + " ");
}
System.out.println();
return size;
}
public static void main(String[] args) {
Integer[] array = new Integer[]{1, 1, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 100, 100, 102, 102, 102, 104, 105, 119, 119, 200, 300, 400, 500};
Integer[] array2 = new Integer[]{1, 1, 3};
Integer[] array3 = new Integer[]{1, 1, 3, 3, 4, 5, 5};
System.out.println("删除后长度:" + removeRepeatNum(array));
}
}
烧脑环节:
4.官方 双指针:
注: 我发现很多题,都用到了双指针解决,比如二分,比如合并两个有序数组,合并两个有序链表!!!很妙的一个解决方式。interesting --!
a.解释:
注:两个字段p,q. p我认为就是我上面的第一层循环,q第二层循环
5. 双指针代码:
package com.nami.algorithm.study.array;
/**
* 描述:
*
* @Author: lbc
* @Date: 2024-03-05 9:41
* @email: 594599620@qq.com
* @Description: keep coding
*/
public class DelRepeatParamOfArray {
/**
* 原版,还有一个加强版。没贴出来,可以自己去题解看下!
*
* @param nums
* @return
*/
public static int removeDuplicates(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int p = 0, q = 1;
while (q < nums.length) {
if (nums[p] != nums[q]) {
nums[p + 1] = nums[q];
p++;
}
q++;
}
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
return p + 1;
}
public static void main(String[] args) {
int[] array = new int[]{1, 1, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 100, 100, 102, 102, 102, 104, 105, 119, 119, 200, 300, 400, 500};
int[] array2 = new int[]{1, 1, 3};
int[] array3 = new int[]{1, 1, 3, 3, 4, 5, 5};
System.out.println("删除后长度:" + removeDuplicates(array));
}
}