用简单通俗易懂的话来记录自己对数组算法的理解
1.原题
1.题目
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
示例 1:
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。
2.分析
1.分析
(1)不能创建新的数组去保存删除后的集合,所以,必须使用临时变量表示删除后的数组的长度。
(2)有序数列最多两个重复,可以想到第i个和第i-2个不能重复,所以,第arr[i]与arr[i-2]进行对比
(3)由于要求必须对原数组进行操作,所以原,要将不重复的数据进行复制。
3.思路
(1)声明临时变量,标记新的数组的大小newSize
(2)遍历整个数组,第i与第i-2的数组对象做对比,如果不同,则newSize++,同时,将num赋值给arr[newSize]
(3)返回去除重复的数组大小newSize
(4)当前是最多两个重复,可以推广到最多K个重复。
4.代码
private int removeDuplicates(int[] arr){
int newArrLength = 0;
for (int i = 0; i < arr.length; i++) {
if ((i < 3) || (arr[i] != arr[i - 2])) {
arr[newArrLength++] = arr[i];
}
}
return newArrLength;
}
结果:
5.巨人肩膀
1.LeetCode通用解法
2.双指针解法也有人认为可以采用双指针揭发,慢指针是指向将要赋值的位置,快指针是正常的遍历。实际上和通用算法思想是一样的。