顺序表、链表刷题指南(力扣OJ)

news2024/11/19 19:47:08

目录

前言

题目一:删除有序数组中的重复项

思路:

题解:

题目二:合并两个有序数组

思路:

分析:

题解:

题目三:反转链表

思路:

分析:

题解:

 题目四:移除链表元素

思路一:

分析:

题解:

思路二:

分析:

题解:

总结


前言

        无论是面试准备还是日常编码实践,解决与顺序表和链表相关的算法问题都是不可避免的挑战,本篇文章旨在帮助你巩固和提升这两个重要数据结构的理解和应用能力。


题目一:删除有序数组中的重复项

 题目描述:

 示例与提示:

 思路:

         题目中的数组是一个升序的数组,依据这个点,我们可以知道,相同的元素都是紧挨着的,那要想保持升序,后一个元素一定比不等于当前元素,且比当前元素大。和前边删除元素的思路类似。

题解:

int removeDuplicates(int* nums, int numsSize){
int pos=0;int src=0;
    while(src<numsSize-1)
    {
        if(nums[src]!=nums[src+1])
        {
            nums[pos++]=nums[src++];
        }
        else
        src++;
    }
    nums[pos++]=nums[src];//为了防止数组越界访问,导致最后一个元素没有进行赋值,最后在这里补上
    return pos;
}

 

 

题目二:合并两个有序数组

 题目描述:

 示例与提示:

         合并两个有序数组的思想叫做归并,这种思路在后续的学习中也会经常遇到。有的同学可能会有这样的思路,将两个元素合并,然后qsort排序一下,这样暴力求解。这样解题也可以,但我们学习了空间复杂度和时间复杂度,就要考虑到复杂度问题,以写出好的程序。

 思路:

         注意:题目中给的是非递减排列的整数数组,举个例子:1,3,4,5,7。这样的数组属于递增数组,1,2,3,3,3,5,6。这样的数组属于非递减数组。

         了解清楚题意后,我们介绍一下解题思路,我们可以依次比较两数组中的元素,然后把小的尾插到新数组,这个就是归并的思想。但是这道题目有点不一样,它的第一个数组会很大,是两个数组有效数据个数的和,这里就要求我们把数据归并到第一个数组。

那这道题应该怎么解决呢?

        前边介绍的归并思想,我们是正着比较,然后尾插,那这道题,我们是不是可以倒着比较,然后尾插到第一个数组。

 分析:

        理解了解题的思路后,我们在进行更深一步的分析,由于力扣的题目大都是接口型题目,在调试时会很麻烦,这就是我们刷不动题的原因之一,做好全面的分析才能更高效的解决问题

 情况一:

 

 从末尾开始,依次比较,较大的数字插入到数组一的末尾:

 

 依次比较,并进行插入。

 情况二:

         两个数组依然是末尾数据进行比较,然后尾插到数组一,但是这次不同的是,数组一遍历完后,还并没有结束,此时的数据如下:

         这里就需要再将数组二剩下的数据继续插入到数组一当中。

 题解:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
int end1=m-1;
int end2=n-1;
int end=m+n-1;
    while(end1>=0 && end2>=0)
    {
        if(nums1[end1] > nums2[end2])
        {
            nums1[end--]=nums1[end1--];
        }
        else
        {
            nums1[end--]=nums2[end2--];
        }
    }
    while(end2 >=0)
        {
             nums1[end--] = nums2[end2--];
        }
}

 

 

         使用3个变量,依次存储第一个数组的有效数据的末尾,第二个数组的末尾,以及第一个数组的末尾。谁大就把他插入到nums1的末尾,最后如果第二个数组没有遍历完,就将剩余数据依次插入到nums1中。

题目三:反转链表

 题目描述:

 思路:

         数组的反转很简单,最后一个元素和第一个元素交换,然后一个往前,一个往后循环遍历,但这个是单链表,没法向前遍历。那要怎么解决呢?我们可以这样做,遍历这个链表,将每个节点依次改为指向前一个节点,但要确保后续节点不丢失。这里我们就可以创建3个结构体指针,一个指向NULL,一个指向第一个节点,最后指向第二个节点,以便于记录链表后续节点。

分析:

        假设初始是这样的一个链表:

         创建3跟结构体指针,改变节点指向后,向后遍历:

         有人疑惑,链表不是不可以向前遍历吗?那n1怎么到n2的位置?我们可以直接把n2赋值给n1,然后把n3赋值给n2,n3通过指针继续向后遍历。

 当n2为NULL时就结束。

 题解:

 分析之后,我们就进行具体实现:

struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* n1,*n2,*n3;
    n1=NULL;
    n2=head;

    if(n2!=NULL)
        n3=n2->next;

    while(n2)
    {
        n2->next=n1;

        n1=n2;
        n2=n3;

        if(n3!=NULL)
            n3=n3->next;
    }
    return n1;
}

 需要注意的是空指针问题,当n3为空时就不要继续向后遍历了。

 

 题目四:移除链表元素

 题目描述:

 思路一:

        这里的思路中规中矩,遍历这个链表,与遇到要删除的val值就删除,但这里需要注意一点特殊情况,尽可能的去多虑特殊情况。

 分析:

         假设初始时给这样一个链表,要删除的是6.

         但是单一的使用指针找到了val的节点,又没法删,需要知道前一个节点。那可不可以使用替换法,把4替换到6节点的位置,遇到val值节点就把后一个节点替换过来,这样就不用使用两个指针了,但如果要删除的节点是尾节点呢?它可没有后一个节点。所以我们还是使用传统的方法。创建一个指针记录前一个节点。

         把val值前一个节点next改为val后一个节点的地址,释放掉cur指向的节点。如果删除节点是最后一个,将prev指向节点的next置为NULL。

         那这种情况呢?如果要删除的节点是头,prev就行不通了。所有我们还需要再多考虑一下头节的情况,进行特殊处理。

        初始情况下cur和head都指向头节点,把cur的下一个节点赋值为head,然后释放掉cur指向的第一个节点,再把新的头head赋给cur。这样就可以解决了。

题解:

        分析完整体思路后,我们进行代码实现,代码如下:

struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode* prev=NULL;
    struct ListNode* cur=head;
   
   
    while(cur)
    {
        if(cur->val==val)
        {
            if(cur==head)
            {
                head=cur->next;
                free(cur);
                cur=head;
            }
            else
            {
               prev->next= cur->next;
               free(cur);
               cur=prev->next;
            }
        }
        else
        {
            prev=cur;
            cur=cur->next;
        }
    }
    return head;
}

 思路二:

        除了传统的方法,还有另外一种方法——尾插法。遍历原链表,如果不是val就尾插到新链表。

分析:

        可以先创建一个新的链表头,初始时链表头为空,然后依次尾插,插入节点。

         这种方法更加简单快捷,没有那么多需要考虑的特殊情况,最后返回新的头。

题解:

        这种方法思路虽然很简单,但在实现时有很多需要注意的点:

struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode* cur=head;
    struct ListNode* newhead=NULL,*tail=NULL;
    while(cur)
    {
        if(cur->val==val)
        {
            struct ListNode* del=cur;
            cur=cur->next;
            free(del);
        }
        else 
        {
            if(tail==NULL)//考虑初始时头和尾都为NULL的情况
            {
                tail=newhead=cur;
            }
            else
            {
                tail->next=cur;
                tail=tail->next;
                
            }
            cur=cur->next;
        }
    }
    if(tail)
        tail->next=NULL;//遍历完之后需要将尾节点next置为NULL,此外还需要注意tail是否为NULL。

    return newhead;
}

         在刷题时我们会发现,很多的操作都是基于我们前边学习的单链表中基本操作的变形,此外解题的思路在很多情况下都是通用的,只需略微变形就可解决问题。所有一定要学会举一反三。

 


 

总结

        刷题不仅是为了应对面试和编码实践,更是为了培养自己的问题解决能力和学习能力。无论是顺序表还是链表,它们都是构建更复杂数据结构的基石,掌握它们对你的编程之路至关重要。最后,感谢阅读!

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

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

相关文章

软考A计划-系统集成项目管理工程师-信息文档和配置管理-上

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

【LeetCode每日一题】——304.二维区域和检索-矩阵不可变

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 中等 三【题目编号】 304.二维区域和检索-矩阵不可变 四【题目描述】 …

【沁恒蓝牙mesh】CH58x flash分区与数据存储管理

本文主要介绍了 沁恒蓝牙芯片 CH58x 的flash 分区与数据存储管理 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是喜欢记录零碎知识点的小菜鸟。&#x1f60e;&#x1f4dd; 个人主页&#xff1a;欢迎访问我的 Ethernet_Comm 博客主页&…

DPG算法

1 一言以蔽之 &#xff08;1&#xff09; DPG是属于确定性策略梯度算法&#xff08;2&#xff09;用于解决连续动作空间问题 2 优点和缺点 2.1 优点&#xff08;1&#xff09;从理论上可以证明&#xff0c;deterministic policy的梯度就是Q函数梯度的期望&#xff0c;这使得…

SAP数据库表维护视图生成器的使用

在SAP中&#xff0c;经常需要自定义数据库表。而且可能需要人工维护数据库表中的数据&#xff0c;可以通过SM30进行维护数据&#xff1b;但是SM30事务的权限太大&#xff0c;不适宜将SM30直接分配&#xff1b;因此&#xff0c;可以通过给维护表分配事务代码&#xff0c;来达到控…

云曦暑期学习第三周——ctfshow--php特性(89-104)

目录 web89 preg_match函数 、数组 web90 intval()函数、强比较 web91 正则修饰符 web92 intval()函数、弱比较 web93 八进制、小数点 web94 strpos() 函数、小数点 web95 小数点 web96 highlight_file() 下的目录路径 web97 数组 web98 三目运算符 web9…

Windows搭建Snort环境及使用方式

目录 0x01 前置环境0x02修改配置文件0x03 自测0x04 使用0x05 感言 0x01 前置环境 环境描述windows10snort2.9.2https://www.snort.org/downloads 先把上面环境下载好&#xff01; 需要注意的是安装npcap这个软件 0x02修改配置文件 软件安装目录&#xff1a;C:/Snort/ 配置文…

有哪些开源和非开源的项目管理工具?

开源和非开源项目管理工具各有其特点和优势。下面是一些常见的开源和非开源项目管理工具以及它们的简要介绍。 开源项目管理工具&#xff1a; OpenProject&#xff1a;OpenProject 是一个功能强大、易于使用的开源项目管理工具。它提供了项目计划、任务管理、团队协作、文档管…

Python开发环境Spyder介绍

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 Spyder简介 Spyder (前身是 Pydee) 是一个强大的交互式 Python 语言开发环境&#xff0c; 提供高级的代码编辑、交互测试、调试等特性&#xff0c;支持包括 Windows、Linux 和 OS X 系统。 &#x1f447; &#x1f44…

【多模态】BLIP——统一视觉语言理解和生成的引导语言图像预训练模型

多模态指的是多种模态的信息&#xff0c;包括&#xff1a;文本、图像、视频、音频等。而多模态研究的就是这些不同类型的数据的融合的问题。目前大多数工作中&#xff0c;只处理图像和文本形式的数据&#xff0c;即把视频数据转为图像&#xff0c;把音频数据转为文本格式。 目录…

PHP 前后端分离,运行配置

H5 WEB目录:安装 yarn install、npm install &#xff08;依赖包&#xff09; 在电脑&#xff1a;安装nodejs Composer下载 &#xff1a;https://getcomposer.org/

彭迦信和梁柱搭班两年,腾讯音乐总市值相对减少约200亿美元

8月1日、8月2日&#xff0c;腾讯音乐-SW&#xff08;HK:01698&#xff0c;下称“腾讯音乐”&#xff09;在港交所的股价连续两日下跌&#xff0c;跌幅分别为2.21%和3.02%。按2023年8月2日的收盘价计算&#xff0c;腾讯音乐的港股市值约为454.17亿港元&#xff0c;总市值约为882…

算法:DFS【深度优先搜索】

概念&#xff1a; 深度优先搜索&#xff08;Depth First Search&#xff09;简称为DFS。一种用于遍历或者搜索树或图的算法。 沿着树的深度遍历树的所有节点&#xff0c;尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或在搜寻时结点不满足条件&#xff0c;则搜索将回溯…

《HeadFirst设计模式(第二版)》第三章代码——装饰者模式

代码文件结构&#xff1a; 星巴兹案例&#xff1a; CondimentDecorator package Chapter3_DecorativeObjects.Decorators;import Chapter3_DecorativeObjects.Beverage;/*** Author 竹心* Date 2023/8/3**/public abstract class CondimentDecorator extends Beverage {Bever…

opencv-34 图像平滑处理-双边滤波cv2.bilateralFilter()

双边滤波&#xff08;BilateralFiltering&#xff09;是一种图像处理滤波技术&#xff0c;用于平滑图像并同时保留边缘信息。与其他传统的线性滤波方法不同&#xff0c;双边滤波在考虑像素之间的空间距离之外&#xff0c;还考虑了像素之间的灰度值相似性。这使得双边滤波能够有…

Scratch 教程 -- 逐字化输出

首先我们来探讨一下对于一个逐字化模块(自定义积木)&#xff0c;有哪些需要设置的参数(请注意&#xff0c;在这里我会先提出一种常规且简便的写法&#xff0c;再进一步讲述其它的优化版本) 1.内容&#xff1a;对于一个文本&#xff0c;其内容是一定需要的(不然你还用啥逐字化啊…

新概念英语的网盘资源

新版新概念英语1-4册全部视频和课本_免费高速下载|百度网盘-分享无限制百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com/s/18wyeA#l…

C++STL——deque容器详解

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.deque容器的基本概念二.deque容器常用操作①deque构造函数②deque元素操作③deque赋值操作④deque交换操作⑤deque大小操作⑥deque插入和删除…

使用IPSEC VPN 在有防火墙的场景和有NAT转换的场景下实现隧道通信实验

目录 一、在有防火墙的场景 1、为所有设备配置对应ip地址&#xff1a; 2、进入两个防火墙实现公网互通 3、测试公网是否互通 4、进入SW1配置IPSEC VPN 5、进入SW2配置IPSEC VPN 6、配置策略方向ESP的流量 7、尝试使用PC1访问PC2 二、在有NAT地址转换的场景 1、为新增加…

C语言中的数据类型有哪些?

有符号数signed可以存储负数&#xff0c;无符号数呢只能存储非负数 我们要考虑两个问题。 第一个问题是要存储的这个整数&#xff0c;它是一个多大的范围&#xff0c;比如说要存储一个五。还有比如说我可能要算个数65535&#xff0c;或者说我要算出一个数65536&#xff0c;可能…