每日一练:删除有序数组中的重复项
注:这里一共有两道题,比较类似,我就把他们合并在一起讲!
删除删除有序数组中的重复项1
链接: 删除有序数组中的重复项1
毫无疑问,这道题要用双指针的方法,因为我们既要瞻前又要顾后! 思路:
1、因为这道题要求让每个元素只出现一次,那么我们就先定义两个指针,一个叫tmp指向第一个数字,另一个叫cur指向第二个数字。 2、然后每次判断一下tmp与cur是否相等,若相等则让cur++,直到找到两个不相等的位置,然后让tmp++,接着让cur处的数字赋给tmp处。 3、cur继续加加,直到出了这个数组为止。
思路比较清晰,我们直接上代码:
int removeDuplicates(int* nums, int numsSize){
int cur = 1;
int tmp = 0;
while(cur < numsSize)
{
if(nums[cur] == nums[tmp])
{
cur++;
}
else
{
tmp++;
nums[tmp] = nums[cur];
cur++;
}
}
return tmp + 1;
}
删除有序数组中的重复项2
链接: 删除有序数组中的重复项2
在写这道题时候,一开始我是这么想的思路 (思路会比等会讲的第二种复杂,所以读者若不想听的话可以直接看第二种) :
1、和第一题一样,先定义两个变量tmp和cur分别用来指向数组第一个数字和第二个数字,然后再定义一个变量k来计算等会重复超过了两次后,多的数。 2、开始循环,判断nums[cur]和nums[tmp] 是否相等,若不相等则让k置为0,若相等则让k加一,然后判断k是否大于等于2,若是则进入子循环对数组进行操作。最后让cur和tmp都加加。 3、若进入子循环,说明这是重复超过两次的数。首先我们先定义个变量num,用于记算一共重复超过多少个数,然后用while循环让cur向后走直到遇到不是这个重复的数。 如果这个时候已经出界了,则直接break返回tmp + 1即可。 若没有出界,再定义一个变量p,记录需要向前挪动多少个数据,即为numsSize - cur。然后用while循环将nums[cur] 处的数据赋给nums[cur - num] 处,循环p次。 最后将cur归位,将numsSize减掉num,再将k置为0。
从步骤就看得出来这种思路比较复杂hhh,但是比较直接一点,有兴趣的读者可以看下代码,没兴趣可以看第二种了hhh:
int removeDuplicates(int* nums, int numsSize){
int cur = 1;
int tmp = 0;
//k用来计算重复超过了两个数后多的数
int k = 0;
while(cur < numsSize)
{
if(nums[cur] == nums[tmp])
{
k++;
if(k >= 2)
{
int num = 0;
while((cur < numsSize) && (nums[cur] == nums[tmp]))
{
num++;
cur++;
}
//判断一下此时cur会不会出界,会直接break
if(cur >= numsSize)
break;
//p用来计算需要向前挪动多少个数据
int p = numsSize - cur;
while(p > 0)
{
nums[cur - num] = nums[cur];
cur++;
p--;
}
cur = tmp + 1;//记得将cur归位
numsSize -= num;//记得将总个数减少,防止后面的循环越界
k = 0;
}
}
else
{
k = 0;
}
cur++;
tmp++;
}
return tmp + 1;
}
好啦进入正题!
在我兴高采烈的写完题后,我去看了一下别人的题解,突然发现,别人只写了几行的代码┭┮﹏┭┮,于是我决定修改我上面的思路,就是简化。
思路:
1、我们先定义两个变量cur 和 tmp,但是这次不同的是,tmp指向数组的第二个数字,cur指向tmp的下一位。
2、接着判断一下数组是否只有一个数字或者两个数字,若是的话直接返回tmp。
3、若前面判断不是只有两个数字以下的数组,则开始遍历cur,直到cur超出了数组的范围。
4、遍历过程中,每次判断一下cur处的数字是否与tmp以及tmp - 1位置的数字相等,若相等则说明重复超过了两次,则让cur++,直到不相等。若不相等了,先让tmp++,然后把cur处的数据赋给tmp处,然后cur++,继续遍历,直到结束。
int removeDuplicates(int* nums, int numsSize){
int cur = 2;
int tmp = 1;
//如果数组只有一个或者两个数,则直接返回tmp
if(cur >numsSize)
return tmp;
while(cur < numsSize)
{
if(nums[cur] == nums[tmp] && nums[cur] == nums[tmp - 1])
{
cur++;
}
else
{
tmp++;
nums[tmp] = nums[cur];
cur++;
}
}
return tmp + 1;
}
这一看是不是就比上面第一种方法思路简洁多啦,而且思路也不复杂,只是一次性拿cur与tmp以及tmp的前一位比较是比较难想到的。
规律总结
类似这种”删除有序数组中的重复项“的题,其实本质就是最多保留n项重复数字,基本都是运用双指针的方法解决。 不仅如此,对于这类题,保留n项重复数字,通过第一题和第二题的比较可以看出,有以下的规律:
1、题目要求最多保留n项重复,那就让tmp指向第n -1项(因为别忘了数组下标是从0开始的),然后让cur指向tmp的下一位。 2、在遍历cur过程中,只需要判断cur处与tmp以及tmp前n - 1项是否相等即可。
这个就是这种题的规律,可以拓展到最多保留3项、最多保留4项…以此类推。
相关文章
- <leetcode刷题-数组>删除排序数组中的重复项
- js 二维数组 添加json数据及js数组与json字符串「建议收藏」
- c语言删除数组中重复元素
- leetcode-26删除有序数组中的重复项(双指针)「建议收藏」
- JS数组删除指定下标元素「建议收藏」
- 【力扣刷题】26. 删除有序数组中的重复项
- js数组的splice方法_js数组删除某一项
- LeetCode | 删除有序数组中的重复项
- 客服系统前端开发:JavaScript删除对象数组中指定key value的对象【唯一客服】网页在线客服系统
- LeetCode 26:删除有序数组中的重复项
- 力扣26-删除有序数组中的重复项
- java数组操作(二)
- 怎么输出数组中的字符串
- PHP 二维关联数组根据其中一个字段排序
- 【力扣/牛客刷题】27. 移除元素 || 26. 删除有序数组中的重复项 || 88. 合并两个有序数组
- 如何在Oracle中删除数组?(oracle删除数组)
- 如何利用数组循环存储至Redis(数组怎么循环存redis)
- 删除数组条目中重复的条目(可能有多个),返回值是一个仅包含被删除的重复条目的新数组。
- phparray_flip()删除数组重复元素
- asp数组重复删除函数(脚本之家增强版)
- Javascript根据指定下标或对象删除数组元素
- pythondictremove数组删除(del,pop)
- PHP删除数组中空值的方法介绍
- PHP如何获取二维数组中某个key的集合