题目描述:
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1,2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0,1,2,3,4.
你不需要考虑数组中超出新长度后面的元素。
这道题,看题目就是去重,但是输出的是去重后的数组长度,用例输出的是不重复数组,刚开始不理解为什么,int型返回的是数组,根据题目提示得出:数组是引用(占内存地址的)的,返回长度,外部根据长度读取数组元素。这样的话就能解释返回值是int,但例子中是数组。
有两种方法。
第一种,我看到这道题第一个想到的就是用集合,集合的特点就是无序且没有重复元素。题目要求是排序后的,那咱们可以用有序集合,Linkedset.来将数组中的元素添加到有序集合中,然后最后最回过去,将去重后的元素赋值给原数组(因为题目要求,不考虑超出的元素。原数组后面的元素不用管)
代码如下:
//第一种方法用集合(有序集合),集合的特点就是元素不重复
int []a = {0,0,1,1,1,2,2,3,3,4};
LinkedHashSet<Integer> set = new LinkedHashSet <> ( ) ;
for (int i = 0;i<a.length;i++){
set.add ( a[i] );
}
int n =0;
for (int j :set){
a[n] = j;
n++;
}
System.out.println(set.size ());
执行结果:
执行时间:
第二种方法:
就是for循环,循环遍历数组,将数组下标i从1开始遍历,将从0开始的元素给另外一个变量,让他从第1个开始,与数组中的第2个比较,相同就跳过,不相同就将i对应的值赋值给这个变量。最后返回这个变量+1,因为这个i是从1开始的。
第二种方法,for循环遍历
int newnum=0;
for (int i=1;i<a.length;i++){
if (a[i]!=a[newnum]){
a[++newnum]=a[i];
}
}
System.out.println(newnum+1);
这里有一点要注意,就是++i,与i++的区别。刚开始学编程老是搞混,++i是先加后赋值,。i++是先赋值后加。这个地方是将newnum从0开始,0.1.2.3.4,(将不重复的数从0-n的下标顺序排列。)每次不相同时,都得将a[i]的值赋值给newnum。
程序用时--时间复杂度是O(n):
总结:
这道题不难,刚上手就有思路,就是去重,用set最简便,但是程序用的时间有点长,用for循环时间短 ,代码也少。两种方法都有优点。明天继续加油
2019-1-22记录