IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C语言数据结构-删除数组中的重复项 -> 正文阅读

[数据结构与算法]C语言数据结构-删除数组中的重复项

1.题目描述:

? ? ? ?给你一个 升序排列 的数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。元素的相对顺序 应该保持 一致 。

? ? ? ?由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么?nums?的前 k 个元素应该保存最终结果。将最终结果插入?nums 的前 k 个位置后返回 k 。不要使用额外的空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array


2.编程思路:

? ? ? ? 对于数据结构题目的编程思路,我建议大家直接画图,画图能够帮助我们更全面地思考问题。首先明确目标是删除有序(升序)数列的重复项。如果我们不考虑时间和空间复杂度,那么最先想到的就是方法1——遍历删除。也就是定义两个序号Start从0开始、End从1开始,如果两者指向的元素相等就说明有重复数据出现,然后将End和以后的数据都向前挪动,直到End指向数组的最后一个元素,如图1所示。

图1

? ? ? ?这种方法能够完成功能,但是并不能满足要求,因为时间复杂度为O(n^2)。所谓时间复杂度就是执行简单代码的次数,上述方法在最坏的情况下(全部都是一样的数据)需要移动(也就是值覆盖)n-1、n-2、...、2、1,利用等差数列求和可以求出一共需要有n*(n-1)/2次赋值操作,所以时间复杂度就是O(n^2)。没有开辟新的空间,所以空间复杂度是O(1)。

? ? ? ?方法2:我们重新开辟一个数组,也用两个序号进行操作,Src遍历指向原数组,Dst遍历指向新开辟的数组。不同的是,我们不移动后面的所有值,而是只要Src和Dst所指向的数据不同就将Src所指向的数据赋给Dst所指向的空间,这里的细节一定要注意,谁走在前面,谁赋值给谁。如图2所示。

?图2

? ? ? 这种方法也能实现功能,但是空间复杂度是O(n),不能满足要求。

? ? ? ? 方法3:我们可以从上面两种简单粗暴的方法中吸取优点,就是让两个序号去遍历,最后将满足条件的的值赋给自己,也就是数组内的值覆盖。如图3所示,我们让Start和End两个序号去遍历原数组,如果两个不等就将Start所指向的数据赋给Dst所指向的空间,这也是所谓的三指针,但是成作序号更好理解。这里有一个细节就是会有End越界的时候,这时候就有最后两个数是相等还是不等两种情况,但是不管是哪种情况都应该把Start所指向的数据赋给Dst所指向的空间。(这点大家画图好好想一下,虽然简单,但是是细节!)

?图3

? ? ? ? 时间复杂度:这个相当于执行n次条件赋值操作,所以就是O(n),空间复杂度为O(1)。

3.代码

int removeDuplicates(int* nums, int numsSize){
    // 处理空数组整个特殊情况
    if(numsSize == 0)
    {
        return 0;   
    }
    // 定义三个序号
    int Start = 0;
    int End = 1;
    int Dst = 0;
    while(End<numsSize)
    {
        // Start End 所指向的数据不等时值覆盖
        if(nums[Start]!=nums[End])
         {
            nums[Dst]=nums[Start];
            End++;
            Start++;
            Dst++;
         }
        // 相等时继续遍历不赋值
        else
        {
            Start++;
            End++; 
        }
    }
    // 考虑End已经越界的时候
    nums[Dst] = nums[Start];
    Dst++;
    return Dst;
}

4.总结

? ? ? ? 对于C语言的数据结构,最重要的就是画图(这能够帮助理清逻辑)、分析复杂度、敲代码!


  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:43:26  更:2022-09-13 11:47:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 14:05:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码