Leetcode刷题笔记之数组篇26. 删除有序数组中的重复项
Posted 大家好我叫张同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode刷题笔记之数组篇26. 删除有序数组中的重复项相关的知识,希望对你有一定的参考价值。
😈博客主页:🐼大家好我叫张同学🐼
💖 欢迎点赞 👍 收藏 💗留言 📝 欢迎讨论! 👀
🎵本文由 【大家好我叫张同学】 原创,首发于 CSDN 🌟🌟🌟
✨精品专栏(不定时更新) 【数据结构+算法】 【做题笔记】【C语言编程学习】
☀️ 精品文章推荐
【C语言进阶学习笔记】三、字符串函数详解(1)(爆肝吐血整理,建议收藏!!!)
【C语言基础学习笔记】+【C语言进阶学习笔记】总结篇(坚持才有收获!)
【Linux编程】一、Linux常见指令和权限理解(思维导图总结)
前言 |
为什么要写
刷题笔记
?
写博客
的过程也是对自己刷题过程的梳理
和总结
,是一种耗时
但有效
的方法。
当自己分享的博客帮助到他人时,又会给自己带来额外的快乐和幸福。
(刷题的快乐+博客的快乐,简直是奖励翻倍,快乐翻倍
有木有QAQ🙈)
题目内容 |
给你一个 升序排列 的数组
nums
,请你原地
删除重复出现的元素,使每个元素 只出现一次,返回删除后数组的新长度。元素的相对顺序
应该保持 一致 。由于在某些语言中不能改变数组的长度,所以必须将结果放在数组
nums
的第一部分。更规范地说,如果在删除重复项之后有k
个元素,那么nums
的前k
个元素应该保存最终结果。 将最终结果插入nums
的前k
个位置后返回k
。
不要使用额外的空间,你必须在原地
修改输入数组 并在使用O(1)
额外空间的条件下完成。
解题过程 |
要想保留非重复项,我们可以采取的一种方式,就是每次都遍历一次前面的数组元素
:
1)如果不出现重复
的,就将其保留到数组
当中。
2)如果出现重复
的就跳过该元素
。这种方式对于有序以及非有序的数组均适用。
时间复杂度为O(N^2)
,空间复杂度为O(1)
【C语言版】
int removeDuplicates(int* nums, int numsSize)
int cur = 0,prev = 0;//保留当前的和上一个的数组下标
for(cur = 0;cur<numsSize;++cur)
int flag = 1;//设置一个标签来记录当前元素cur是否跟前面的元素重复,默认1表示不重复
for(int i = 0;i<cur;++i)
if(nums[i] == nums[cur])
flag = 0;//如果出现重复就将标签flag改为0
if(flag == 1)//只有当标签为1的时候,才将cur元素放到数组中
nums[prev++] = nums[cur];
return prev;//最终prev代表的就是数组中元素的个数
【C++版】
class Solution
public:
int removeDuplicates(vector<int>& nums)
int cur = 0,prev = 0;
for(cur = 0;cur < nums.size();++cur)//用nums.size()来获取数组的长度
int flag = 1;
for(int i = 0;i < cur;++i)
if(nums[i] == nums[cur])
flag = 0;
if(flag == 1)
nums[prev++] = nums[cur];
return prev;
;
可以看到用C语言可以通过测试,但是内存耗时是比较长的,用C++就更加明显,根本就通过不了测试,超出时间限制了。
思路优化 |
考虑到目前数组中的元素已经按照升序
排列了,那么重复的元素一定是紧挨着放的
,比如 1 1 2 3 3 4 7,1和1、3和3 都是紧挨着的。所以我们可以考虑用双下标+虚拟数组
的方式来处理这个问题。假设有两个下标prev、cur,cur往后遍历,如果cur所在元素和prev不一样,就将其给到prev,然后继续向后遍历,如果cur和prev一样,那就直接跳过这个元素。
假设输入:nums = [0,0,1,1,1,2,2,3,3,4]
prev从第一个元素开始,cur要从第二个元素开始,如果数组的元素个数小于两个,直接返回数组,因为这种情况下,不可能存在重复元素
当下标cur和prev元素相同时,cur直接往后走
当cur和prev指向元素不相同时,先让prev往后走一步,然后将cur的元素给到prev,然后cur再往后走一步
cur指向的两个1和prev相同,跳过,到达2的位置
先让prev移动到下一个位置,然后将cur指向的2给到prev,然后cur再往后走一步
直到cur遍历完整个数组结束。
【完整的算法图解】
【C语言版】
int removeDuplicates(int* nums, int numsSize)
if(numsSize < 2)//如果数组的元素小于2个,就不可能存在重复元素,直接返回
return numsSize;
int prev = 0,cur = 1;//prev从第一个元素开始,cur从第二个元素开始
while(cur < numsSize)
if(nums[cur] != nums[prev])//如果cur指向元素和prev不一样
nums[++prev] = nums[cur++];//先让prev向后走一步,然后将cur元素给到prev,之后cur再向后走一步
else
++cur;//如果cur和prev元素相同,直接跳过该元素,cur直接向后走一步
return prev + 1;//最终prev指向最后一个元素的下标,元素个数等于prev+1
【C++版】
class Solution
public:
int removeDuplicates(vector<int>& nums)
if(nums.size() < 2)//如果元素小于2个,直接返回
return nums.size();
int prev = 0,cur = 1;
while(cur < nums.size())
if(nums[cur] == nums[prev])
++cur;
else
nums[++prev] = nums[cur++];
return prev + 1;
;
以上是关于Leetcode刷题笔记之数组篇26. 删除有序数组中的重复项的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode刷题笔记之数组篇26. 删除有序数组中的重复项