原题网址:http://www.lintcode.com/zh-cn/problem/remove-duplicates-from-sorted-array/#
给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度。
不要使用额外的数组空间,必须在原地没有额外空间的条件下完成。
样例
给出数组A =[1,1,2],你的函数应该返回长度2,此时A=[1,2]。
标签
思路1:
最开始的想法是for循环遍历,循环变量i从size-1开始,当i大于0时:
如果当前元素与前一个元素相等,当前元素之后的元素整体左移一个索引,全部左移完成后,删除最后一个元素;
如果不相等,i--。
程序在VS2010上可以通过,但放到lintcode上现实超时……好吧,换一个思路。
思路2:
还是for循环遍历,但循环体内再加一个while循环,找到与当前元素相等的所有元素并记录下标范围,然后一起删除,这次AC了,代码如下:
注意:vec.erase(vec.begin()+i,vec.begin()+j); 删除区间[i,j-1],区间从0开始,i,j为数组下标。
也就是说如果想删除区间[i,j]应写成vec.erase(vec.begin()+i,vec.begin()+j+1);
class Solution {
public:
/*
* @param nums: An ineger array
* @return: An integer
*/
int removeDuplicates(vector<int> &nums) {
// write your code here
int i=0;
for (;i<(int)nums.size()-1;i++)
{
int s=i;
while(i<(int)nums.size()-1&&nums[i]==nums[i+1])
{
i++;
}
if (i>s)
{
nums.erase(nums.begin()+s+1,nums.begin()+i+1);
}
i=s;
}
return (int)nums.size();
}
};
思路3:
在网上查了查,果然能发现更好的方法,学无止境……
感觉有点类似于插入排序,将数组分为两段,前一段是已经删除重复元素的数组,后一段是未删除重复元素的数组;
用下标 i 指向非重数组最大值(即数组最右边的元素),下标 j 指向重复数组中第一个与非重数组中元素不同的元素;
将 j 指向的元素值赋给 i+1 指向的元素,即可增大非重数组;
AC代码:
class Solution {
public:
/*
* @param nums: An ineger array
* @return: An integer
*/
int removeDuplicates(vector<int> &nums) {
// write your code here
int size=nums.size();
if (size==0)
{
return 0;
}
int i=0,j=1;
while(j<size)
{
if (nums[j]!=nums[i])
{
nums[i+1]=nums[j];
i++;
j++;
}
else
{
j++;
}
}
nums.resize(i+1);
return i+1;
}
};