删除有序数组中的重复——通解
给你一个有序数组 arr ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
源代码:
/*
* 2021-4-6 LeetCode每日一题改版
* 对有序数组去除相同元素,每个值只保存K个相同值
* 解题思路:
* 本题有两个基本特性:1.有序数组 2.保留k个有效值
* 可以利用快(fast)慢(slow)指针遍历数组来解决问题。
*
* fast指针负责遍历数组,fast指针所指的元素就是正在被“审查”是否“有效”的元素。
* 这里的“有效”是指元素的值出现不超过K次
*
* slow指针代表最新一个已经判定为“有效”的元素在数组中的位置的下一个位置
* 注意:这里是“已经”是指slow往前的元素都是有效元素
* slow指向下一个“审查”为有效的数据应该存放的位置
*
* 快慢指针的工作方式是:
* 当arr[fast]!=arr[slow-k]时,代表fast所指元素有效——用逆否命题更好理解:当arr[fast]无效,则arr[fast]==arr[slow-k];
* 应当把arr[fast]拷贝到arr[slow],并且slow往后移动一位,数组有效长度加一
* fast往后移动一位,继续“审查”下一个元素
* 否则,fast所指元素无效
* 应当只将fast往后移动一位,继续“审查”下一个元素
*
* 当fast遍历完所有数组元素时,结束函数。
*
* 因为前k个元素一定有效,所以为了提高程序性能,建议直接从第K+1个元素开始审查
* 所以fast的初始值应当为k(指向第k+1个元素),slow的初始值应当为k-1(指向第k个元素)
*
* 注:arr[slow-k]与arr[fast]的比较是这个题解的关键,他的核心思想是:
* arr[0]-arr[slow-1]是当前的有序的有效数组
* 当arr[slow-k]==arr[fast]时,arr[fast]至少已经是第k+1次出现,不应该加入到有效数组中,故而fast++,而slow不变
* 其他情况下,arr[fast]所指元素都是有效的,即应该将它拷贝到arr[fast]加入有效数组,slow++,fast++。
*/
template<typename T>
int removeKDuplicates(T arr[], int n , int k)
{
if (n <= k)
return n;
int slow = k, fast = k;
while (fast < n)
{
if (arr[slow - k] != arr[fast])
{
arr[slow++] = arr[fast];
}
fast++;
}
return slow;
}