题目要求:
duplicates 去除重复
已知有序数组,要求原地删除重复,返回长度
空间复杂度要求: O(1)
时间复杂度要求:无
//纯 C
int RemoveDu(int* nums,int length) {
int i = 0;
for (int j = 0; j < length; j++) {
if (nums[i] != nums[j])
nums[++i] = nums[j];
}
return i + 1;
}
void main()
{
int nums[] = { 0,0,1,1,1,2,2,3,3,4 };
int length = RemoveDu(nums,sizeof(nums) /4);
}
//c++
int RemoveDu(vector<int> &nums) {
int i = 0;
for (int j = 0; j < nums.size(); j++) {
if (nums[i] != nums[j])
nums[++i] = nums[j];
}
return i + 1;
}
void main()
{
//int nums[] = { 0,0,1,1,1,2,2,3,3,4 };
vector<int> nums = { 0,0,1,1,1,2,2,3,3,4 };
int length = RemoveDu(nums);
}
小结
要求原地操作,题目中没有提供额外的空间,考虑使用在数组内操作。那么对于数组内操作的话,想到swap()元素这种操作。又是一个已经排序好了的数组。考虑使用两个指针。
- 慢指针 i 放在头部 快指针 j 向后移动 value[i] != value[j] 就是跨越了重复
- value[++i] = value[j] 不需要关注之后的数据 长度等于 i+1
算法来说空间复杂度为:O(n)
去除重复:这个功能个人认为在实际业务场景中还会比较常用的。其实C++已经实现了这个功能std::unique()。
std::unique()
该函数的作用是“去除”容器或者数组中相邻元素的重复出现的元素,注意
- 这里的去除并非真正意义的erase,而是将重复的元素放到容器的末尾,返回值是去重之后的尾地址。
- unique针对的是相邻元素,所以对于顺序顺序错乱的数组成员,或者容器成员,需要先进行排序,可以调用std::sort()函数
#include <algorithm>
int nums[] = { 5,5,7,7,3,3,2,2,1} ;
int* position = std::unique(nums,nums+sizeof(nums)/4);
早上在地铁上看到这个题目,直接看题解说用快慢指针,自己凭着对快慢指针的理解推导了一下,没有成功。下午做了出来,从题目角度来说其实比较简单。