顺序表算法题 —— 移除元素、删除有序数组中的重复项、合并两个有序数组

news2024/9/28 10:19:18

目录

一、顺序表算法题

1、移除元素

2、删除有序数组中的重复项 

3、 合并两个有序数组

二、顺序表问题与思考


一、顺序表算法题

1、移除元素

移除元素 - 力扣(LeetCode)

思路分析:

思路一:创建一个新数组,开辟新空间,把符合条件的元素放到新数组中,再释放和销毁旧空间。

思路二:用顺序表査找指定元素,并返回该指定元素的下标,再删除指定下标的位置。

思路三:用一个顺序表查找指定元素,逐个查找指定元素,与符合条件的元素删除,后面往前挪动一个位置。

我们现在以思路三来详细分析一下:

第一层循环:遍历数组,查找val。

第二层循环:val之后的数据整体往前挪动一位。

时间复杂度为O(n^2),对于需要查找多次的复杂算法题比较不友好,运行时间长;

但对于这一道带提示条件的简单算法题,就没有时间限制的要求,所以就无需关心时间复杂度。

但对于追求更高要求的时间和空间的相关算法复杂度的精度,我们从以下思路来入手:

最终思路:

该思路的时间复杂度为O(n);空间复杂度为O(1)。

定义两个变量指向数组第一个位置,判断nums[src]是否等于val,所以有以下两者情况:

(1)当nums[src]等于val,所以src++;

(2)当nums[src]不等于val,所以nums[dst]=nums[src],src++,dst++。

我们就这个数组例子来分析一下:

(1)因为nums[src]等于val,所以src++;当src++后,nums[src]为数组第二个元素的位置,nums[src]不等于val,nums[dst]=nums[src],此时数组第一个元素被赋值为2,再src++,dst++。

(2) 当src++和dst++后,nums[src]为数组第三个元素的位置,nums[sdst]为数组第二个元素的位置。nums[src]不等于val,nums[dst]=nums[src],此时数组第二个元素被赋值为2,再src++,dst++。

(3) 当src++和dst++后,nums[src]为数组第三个元素的位置,nums[dst]为数组第二个元素的位置。此时nums[src]等于val,所以src++。

(4) 此时nums[src]在后面数组外,超出数组的范围,即可为不满足src小于numsSize的条件,跳出循环,返回dst值。

运行代码: 

int removeElement(int* nums, int numsSize, int val) 
{
    int src = 0;
    int dst = 0;
    while(src < numsSize)
    {
        if(nums[src] == val)
        {
            src++;
        }
        else
        {
            nums[dst++] = nums[src++];
            //dst++;
            //src++;
        }
    }
    //此时dst指向的位置就是要返回的有效个数
    return dst;
}

运行提交结果:

 

2、删除有序数组中的重复项 

删除有序数组中的重复项 - 力扣(LeetCode) 

 

思路分析:

思路一:指针指向第一个元素,然后与它后面的元素进行比较,若相等,第一个元素和它后面的一个元素以外的整体前移;若不相等,则指针后移一位,以此类推。

思路二:定义两个变量,dst为第一个位置,src为第一个位置的下一个位置,判断src和dst位置的数据,因此有以下两者情况:

(1)若相等,src++;

(2)若不相等,dst++,nums[dst]=nums[src],src++。

思路二只有一层循环,时间复杂度为O(n);空间复杂度为O(1)

我们以思路二的一个例子来入手分析一下:

(1)此时nums[dst]==nums[src],所以src++,此时src为第三个元素的位置。

(2)此时nums[dst] != nums[src],则dst++,此时dst为第二个元素的位置,所以使nums[dst]=nums[src],再让src++。

(3)此时nums[src]在后面数组外,超出数组的范围,即可为不满足src小于numsSize的条件,跳出循环,返回dst值。

总结规律:

        两个重复的元素必定相邻,不可能中间有间隔的元素,所以直接相当于把重复的元素删掉,只保留不重复的元素,保持有序性。

运行代码: 

int removeDuplicates(int* nums, int numsSize) 
{
    int dst = 0, src = dst+1;
    while(src < numsSize)
    {
        //nums[dst]  nums[src]
        //相同(重复) src++
        //不相同,dst++,赋值,src++
        if(nums[dst] != nums[src] && ++dst != src)
        {
            nums[dst] = nums[src];
        }
        src++;
    }
    return dst+1;
}

运行提交结果:

 

3、 合并两个有序数组

合并两个有序数组 - 力扣(LeetCode)

思路分析:

        根据题目要求,我们可以创建三个指针,分别指向num1最后一个有效数据位置,num2最后一个数据位置,和num1最后一个位置,比较了l1和l2位置的数据,谁大,谁就往l3位置放数据,同时往l3放数据的这个指针和l3这个指针往前移动一个位置,另一个指针不动,继续以上操作。

结束条件:以两种情况为主

(1)l1<0:要处理nums2中数据,循环放到num1中。

(2)l2<0:不需要处理,因为nums2中的数据已经有序的放到num1中了。

我们以该思路分析以下例子:

        最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

(1)l1和l2的数据相比较,l1的数据大,放到l3的位置处。

(2)同时l1和l3往前移动一个位置 ,l2不动。

 (3)以此类推,重复以上操作,直到l1或l2其中之一指向数组之外。

情况一:

        此例子是l2指向数组之外,即l2<0,此时表明不需要处理,因为nums2中的数据已经有序的放到num1中了。

情况二:

        我们以另一种情况来看,即l1<0,要处理nums2中数据,循环放到num1中,同时往l3放数据的这个指针和l3这个指针往前移动一个位置,另一个指针不动。

该思路只有并列的两层循环,时间复杂度为O(n)或O(m);空间复杂度为O(1)

运行代码:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{
    int l1 = m - 1;
    int l2 = n -1;
    int l3 = m + n - 1;

    //l1 >= 0  l2 >= 0
    while(l1 >= 0 && l2 >= 0)
    {
        if(nums1[l1] > nums2[l2])
        {
            nums1[l3--] = nums1[l1--];
        }
        else
        {
            //l1 == l2 要么 l2 > l1
            nums1[l3--] = nums2[l2--];
        }
    }
    //跳出while有两种情况:要么l1 < 0(需要处理),要么l2 < 0(不需要处理)
    while(l2 >= 0)
    {
        nums1[l3--] = nums2[l2--];
    }       
}

运行提交结果:

 

进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗? 

        为了利用数组 nums 1与 nums 2已经被排序的性质,我们可以使用双指针方法。这一方法将两个数组看作队列,每次从两个数组头部取出比较小的数字放到结果中。

初始两数组状态如下:

排序后的效果:

 

运行代码:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{
    int p1 = 0, p2 = 0;
    int sorted[m + n];
    int cur;
    while (p1 < m || p2 < n) 
    {
        if (p1 == m) 
        {
            cur = nums2[p2++];
        } 
        else if (p2 == n) 
        {
            cur = nums1[p1++];
        } 
        else if (nums1[p1] < nums2[p2]) 
        {
            cur = nums1[p1++];
        } 
        else 
        {
            cur = nums2[p2++];
        }

        sorted[p1 + p2 - 1] = cur;
    }

    for (int i = 0; i != m + n; ++i) 
    {
        nums1[i] = sorted[i];
    }
}

复杂度分析:

  1. 时间复杂度:O(m+n)。指针移动单调递增,最多移动 m+n 次,因此时间复杂度为 O(m+n)。
  2. 空间复杂度:O(m+n)。需要建立长度为 m+n 的中间数组 sorted。

二、顺序表问题与思考

  1. 中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容⼀般是呈2倍的增长,势必会有⼀定的空间浪费。例如当前容量为100,满了以后增容到200, 我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
思考:如何解决以上问题呢?这就需要引入链表的相关内容了,请听下回博客详细分解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2173171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

828华为云征文|在Flexus X实例上安装JDK和Tomcat保姆教学

目录 一、Flexus云服务器X实例 1.1 Flexus X实例概述 1.2 Flexus X实例场景优势 1.3 其他型号与Flexus X实例比较 二、Flexus X实例上安装JDK 2.1 确定安装版本 2.2 yum命令直接安装 2.3 查看版本 三、Flexus X实例上安装tomcat 3.1 上传安装包到Flexus X实例服务器 …

拯救Air780EP模块紧急项目:异常断链的吐血经历。。。

小编最近被老板驱使&#xff0c;要用Air780EP模块做几个紧急项目 并且由于时间紧任务重&#xff0c;遇到了一些棘手问题&#xff0c;简直呕心沥血…… 左思右想&#xff0c;还是在这里把遇到的问题&#xff0c;排查记录下来 也许可以帮到因遇到类似的问题&#xff0c;并且一…

你要的Air201录音和播放录音功能?直接拿去!

最近拼拼收到同学们的疑问&#xff1a;Air201是否支持录音、播放录音功能&#xff1f; 必须支持&#xff01;Air201可是高集成化设计&#xff0c;并且Air201自带了ES8311音频解码芯片&#xff08;Audio Codec&#xff09;及MIC麦克&#xff0c;可支持本地的录音功能&#xff1…

掌握编码最佳实践

你准备好把你的编程技能提升到一个新的水平了吗&#xff1f;在本文中&#xff0c;我们将探讨秘密破坏您的生产力的常见编码错误&#xff0c;并分享您需要了解的优化工作流程的最佳实践。 通过实施这些技巧&#xff0c;您将更快&#xff0c;更智能地编码&#xff0c;并在创纪录…

预训练词向量的使用

目录 1.代码实现 2.知识点&#xff1a; 两个网站可以下载预训练词向量 GloVe网站&#xff1a;GloVe: Global Vectors for Word RepresentationfastText网站&#xff1a;https://fasttext.cc 1.代码实现 import os import torch from torch import nn import dltools class …

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑异步区域调频资源互济的电能、惯性与一次调频联合优化出清模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Web后端开发原理!!!什么是自动配置???什么是起动依赖???

引言&#xff1a; 当然&#xff0c;在我们学习的过程中&#xff0c;得知其然&#xff0c;还得知其所以然。So理解了其原理&#xff0c;更能让我们对其开发的理解&#xff0c;遇到问题&#xff0c;也更能快速找到解决办法&#xff01;&#xff01;&#xff01; 1. SprngBoot-配…

网站建设中,营销型网站与普通网站有什么区别

营销型网站与普通网站在建站目的、交互设计以及结构优化等方面存在区别。以下是具体分析&#xff1a; 建站目的 营销型网站&#xff1a;以销售和转化为主要目标&#xff0c;通过专业的市场分析和策划来吸引潜在客户&#xff0c;并促使其采取购买行动。普通网站&#xff1a;通常…

Golang | Leetcode Golang题解之第441题排列硬币

题目&#xff1a; 题解&#xff1a; func arrangeCoins(n int) int {return sort.Search(n, func(k int) bool { k; return k*(k1) > 2*n }) }

Python in Excel作图分析实战!

Excel 中的 Python 现已正式发布&#xff0c;适用于 Microsoft 365 商业版和企业版的 Windows 用户。去年 8 月&#xff0c;微软与 Anaconda 合作&#xff0c;通过集成 Python 为 Excel 引入了一个令人兴奋的新增功能&#xff0c;从而可以将 Python 和 Excel 分析无缝结合到同一…

OLMo - 训练和使用AI2 模型

文章目录 一、关于 OLMo安装 二、模型概览Checkpoints 三、推理关于微调检查点的推理量化 四、Reproducibility训练检查训练数据 五、微调六、评估 一、关于 OLMo OLMo: Open Language Model OLMo是一个用于训练和使用AI2最先进的开放语言模型的存储库。它由科学家为科学家构建…

java初识

目录 1.命名规范 2.数据类型 3.数据类型转换&#xff08;就是见识一下&#xff09; 4.java里面的输入输出 4.1判断是不是偶数 4.2判断是不是闰年 4.3其他的输入输出 4.4顺序的问题 5.分支语句补充 5.IDEA里面的调试 6.continue的一个案例 1.命名规范 这个命名规范就…

【Mysql】Mysql数据库基本操作-------DDL(中)

1、对表结构的常用操作----创建表 创建表格式&#xff1a; creat table (if not exists ) (可以省略&#xff09; 表名( 字段一 类型[&#xff08;宽度&#xff09;] [约束条件] [comment 字段说明], 字段二 类型[&#xff08;宽度&#xff09;] [约束条件] […

翻译:Recent Event Camera Innovations: A Survey

摘要 基于事件的视觉受到人类视觉系统的启发&#xff0c;提供了变革性的功能&#xff0c;例如低延迟、高动态范围和降低功耗。本文对事件相机进行了全面的调查&#xff0c;并追溯了事件相机的发展历程。它介绍了事件相机的基本原理&#xff0c;将其与传统的帧相机进行了比较&am…

Github 2024-09-28Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-09-28统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Starlark项目1Python项目1TypeScript项目1Pake: 利用 Rust 轻松构建轻量级多端桌面应用 创建周期:491 天开发语言:Rust协议类型:M…

Linux云计算 |【第四阶段】RDBMS1-DAY2

主要内容&#xff1a; 常用函数&#xff08;函数分类1&#xff1a;单行、分组&#xff1b;函数分类2&#xff1a;字符、数学、日期、流程控制&#xff09;、分组查询group by、连接查询 一、常用函数 1. 按使用方式分类 ① 单行函数 单行函数&#xff08;Scalar Functions&…

LeetCode[中等] 78.子集

给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 思路 迭代法 每次遍历nums中的新的数&#xff0c;将其加到之前所有得到的set中&#xff0c…

多个树模型特征贡献度与可视化

背景 在机器学习中&#xff0c;特征的重要性是了解模型如何做出预测的关键指标之一&#xff0c;在树模型中&#xff0c;特征重要性通常通过特征的分裂节点来衡量&#xff0c;通过观察特征在模型中的贡献&#xff0c;可以对数据集中的重要特征有更深入的理解&#xff0c;之前的…

F28335 的 EPWM 外设

1 PWM 简介 2 F28335的ePWM介绍 2.1 时基模块TB &#xff08;1&#xff09;时基模块的功能 &#xff08;2&#xff09;时基模块的关键信号和寄存器 给出时基模块内部结构图来了解里面的关键信号和寄存器&#xff0c;时基模块内部结构图如下所示&#xff1a; &#xff08;3…

十一假期地区人流量出行大数据分析:技术驱动下的深度洞察

随着国庆黄金周的临近&#xff0c;旅游市场再次迎来了一年一度的出行高峰。在这个数字化时代&#xff0c;如何利用大数据、第三方接口等先进技术进行数据采集与分析&#xff0c;以更精准地预测人流量、优化资源配置、提升旅游体验&#xff0c;成为了行业内外关注的焦点。 一、…