当前位置: 首页 > news >正文

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

目录

前言

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

思路:

题解:

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

思路:

分析:

题解:

题目三:反转链表

思路:

分析:

题解:

 题目四:移除链表元素

思路一:

分析:

题解:

思路二:

分析:

题解:

总结


前言

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


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

 题目描述:

 示例与提示:

 思路:

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

题解:

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++];}elsesrc++;}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;
}

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

 


 

总结

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

相关文章:

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

目录 前言 题目一&#xff1a;删除有序数组中的重复项 思路&#xff1a; 题解&#xff1a; 题目二&#xff1a;合并两个有序数组 思路&#xff1a; 分析&#xff1a; 题解&#xff1a; 题目三&#xff1a;反转链表 思路&#xff1a; 分析&#xff1a; 题解&#xff1a; 题目四&…...

Lambda表达式总结

Lambda作为Java8的新特性&#xff0c;本篇文章主要想总结一下常用的一下用法和api 1.接口内默认方法实现 public interface Formula {double calculate(int a);// 默认方法default double sqrt(int a) {return Math.sqrt(a);} }public static void main(String[] args) {Form…...

岛屿的最大面积

给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0&#xff08;代表水&#xff09;包围着。 岛屿的面积是岛上值为 1 …...

迭代器模式(Iterator)

迭代器模式是一种行为设计模式&#xff0c;可以在不暴露底层实现(列表、栈或树等)的情况下&#xff0c;遍历一个聚合对象中所有的元素。 Iterator is a behavior design pattern that can traverse all elements of an aggregate object without exposing the internal imple…...

Goland搭建远程Linux开发

Windows和Linux都需要先构建好go环境&#xff0c;启用ssh服务。 打开Windows上的Goland&#xff0c;建立项目。 点击添加配置&#xff0c;选择go构建 点击运行于&#xff0c;选择ssh 填上Linux机器的IP地址和用户名 输入密码 没有问题 为了不让每次运行程序和调试程序都生…...

react中PureComponent的理解与使用

一、作用 它是一个纯组件&#xff0c;会做一个数据的浅比较&#xff0c;当props和state没改变的时候&#xff0c;不会render重新渲染&#xff0c; 改变后才会render重新渲染&#xff0c;提高性能。 二、使用 三、注意 它不能和shouldComponentUpdate生命周期同时使用。因为它…...

洛谷——P5714 【深基3.例7】肥胖问题

文章目录 题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 AC代码 题目 题目描述 BMI 指数是国际上常用的衡量人体胖瘦程度的一个标准&#xff0c;其算法是 m h 2 \dfrac{m}{h^2} h2m​&#xff0c;其中 m m m 是指体重&am…...

Mac隐藏和显示文件

由于之前没有使用过Mac本&#xff0c;所以很多地方都不太清楚&#xff0c;在下载git项目的时候&#xff0c;发现没有.git文件&#xff0c; 一开始还以为下载错了&#xff0c;但是git命令是可以看到远端分支以及当前分支的&#xff0c;之后在一次解压文件的时候发现&#xff0c;…...

软件工程中应用的几种图辨析

【软件工程】软件工程中应用的几种图辨析&#xff1a;系统流程图、数据流图、数据字典、实体联系图、状态转换图、层次方框图、Warnier图、IPO图、层次图、HIPO图、结构图、程序流程图、盒图、PAD图、判定表_眩晕李的博客-CSDN博客 软件工程——实体关系图 状态转换图 数据流…...

下载离线版的VS Visual Studio 并下载指定的版本

一、先下载引导程序 下载地址VS VisualStudio官网 在这个页面翻到最下面 在这里下载需要的版本 下载引导程序 二、下载离线安装包 写一个批处理文件&#xff08;vs.bat&#xff09; 命令格式如下 <vs引导程序exe> --layout <离线安装包下载的路径> --add <功能…...

Eureka 学习笔记5:InstanceRegistry

版本 awsVersion ‘1.11.277’ LeaseManager 接口管理实例的租约信息&#xff0c;提供以下功能&#xff1a; 注册实例取消注册实例实例续约剔除过期实例 public interface LeaseManager<T> {/** 注册实例并续约*/void register(T r, int leaseDuration, boolean isRep…...

System Verilog——虚方法的使用

1、使用虚方法目的 通过在父类里定义虚方法(task or function)&#xff0c;可以在当父类句柄调用一个方法时候&#xff0c;前提是若是这个句柄指向了子类对象&#xff0c;则调用的方法为子类的方法而不是父类的方法。 1.1、实例理解&#xff1a;将子类句柄赋值成父类句柄 mod…...

线性规划和单纯形法-原理篇

文章目录 引言线性规划标准型问题特点单纯形法 引言 很多运筹学的教材都是从线性规划开始的&#xff0c;我平时做算法策略的落地应用时也研发了一部分基于线性规划的技术方案。可以说&#xff0c;如果搞不懂线性规划&#xff0c;很难成为一名优秀的运筹优化算法工程师。 但是…...

FBX SDK开发快速上手指南

一段时间以来&#xff0c;我一直想制作一个 FBX Exporter 将 FBX 文件转换为我自己的格式。 整个过程不是很顺利&#xff0c;主要是FBX的官方文档不是很清楚。 另外&#xff0c;由于 FBX 格式被许多应用程序使用&#xff0c;而不仅仅是游戏引擎&#xff0c;因此提供的示例代码没…...

探讨|使用或不使用机器学习

动动发财的小手&#xff0c;点个赞吧&#xff01; 机器学习擅长解决某些复杂问题&#xff0c;通常涉及特征和结果之间的困难关系&#xff0c;这些关系不能轻易地硬编码为启发式或 if-else 语句。然而&#xff0c;在决定 ML 是否是当前给定问题的良好解决方案时&#xff0c;有一…...

Git笔记--Ubuntu上传本地项目到github

目录 1--基本配置 2--本地上传 1--基本配置 ① 创建ssh-key cd ~/.sshssh-keygen -t rsa -C "邮箱地址"② 查看并关联ssh-key gedit id_rsa.pub 复制内容&#xff0c;在 GitHub 中依次点击 Settings -> SSH and GPG keys -> New SSH key&#xff0c;将 id…...

基于Go编写一个可视化Navicat本地密码解析器

前提 开发小组在测试环境基于docker构建和迁移一个MySQL8.x实例&#xff0c;过程中大意没有记录对应的用户密码&#xff0c;然后发现某开发同事本地Navicat记录了根用户&#xff0c;于是搜索是否能够反解析Navicat中的密码掩码&#xff08;这里可以基本断定Navicat对密码是采用…...

Maven【入门笔记】

Maven 解决版本依赖的问题 https://www.liaoxuefeng.com/wiki/1252599548343744/1309301146648610 如果没有项目管理工具&#xff0c;在开发项目的时候&#xff0c;我们需要手动管理依赖包&#xff0c;需要管理依赖包的版本、去找到并下载依赖包、还有依赖包所依赖的包 等等。…...

Android Studio中使用cmake开发JNI实战

JNI学习大纲 一、JNI编程入门 二、Android Studio中使用cmake开发JNI实战 第一章节我们介绍了JNI的开发步骤&#xff0c;那这一章节我们就开始在Android Studio中实战一下吧&#xff0c;Lets Start。 1. Android Studio中安装CMake插件 AS中菜单栏选择Tools>SDK Manager在…...

第七章 图论

第七章 图论 一、数据结构定义 图的邻接矩阵存储法#define MaxVertexNum 100 // 节点数目的最大值// 无边权&#xff0c;只用0或1表示边是否存在 bool graph[MaxVertexNum][MaxVertexNum];// 有边权 int graph[MaxVertexNum][MaxVertexNum];图的邻接表存储法 把所有节点存储为…...

SEO 推广与传统广告推广有什么区别

SEO 推广与传统广告推广有什么区别 在当今的数字化时代&#xff0c;企业如何有效地推广自己的产品和服务成为了一个亟待解决的问题。两种常见的推广方式——SEO 推广与传统广告推广——各有优劣&#xff0c;企业需要根据自身的需求和市场环境进行选择。本文将详细探讨SEO推广和…...

DRM显示框架中的“导演”:深入理解CRTC如何协同Plane与Connector工作

DRM显示框架中的“导演”&#xff1a;深入理解CRTC如何协同Plane与Connector工作 想象一下&#xff0c;当你在电影院观看一部大片时&#xff0c;银幕上的每一帧画面都经过精心编排——主角的位置、特效的时机、放映机的同步&#xff0c;所有这些元素都需要一个核心指挥者来协调…...

Ostrakon-VL-8B辅助作业批改实战:识别手写公式与图表

Ostrakon-VL-8B辅助作业批改实战&#xff1a;识别手写公式与图表 每次批改理科作业&#xff0c;是不是都感觉眼睛快看花了&#xff1f;特别是面对几十份甚至上百份的手写作业&#xff0c;那些密密麻麻的公式、歪歪扭扭的电路图&#xff0c;还有各式各样的化学符号&#xff0c;…...

Linux系统学习:38张思维导图构建核心知识体系

1. Linux学习思维导图概述作为一名从嵌入式开发转战云计算的老兵&#xff0c;我深知系统化学习Linux的重要性。最近整理硬盘时翻出一套珍藏多年的学习资料——38张涵盖Linux核心知识体系的思维导图&#xff0c;这些图纸曾帮助我顺利通过RHCE认证&#xff0c;也指导过团队新人快…...

【限时开源】Polars 2.0清洗模板库V1.0发布:含金融时序对齐、电商ID映射、日志正则归一化等9大高复用Pipeline

第一章&#xff1a;Polars 2.0大规模数据清洗技巧入门到精通教程 Polars 2.0 是专为高性能、内存安全与并行计算设计的 DataFrame 库&#xff0c;其惰性执行引擎与零拷贝语义使其在处理 GB 级别结构化数据时显著优于 Pandas。本章聚焦真实场景下的数据清洗实践&#xff0c;涵盖…...

如何写 Skill

核心概念 Skill 是一个自包含的模块&#xff0c;用来给 Claude/Cascade 注入特定领域的知识、工作流和工具。本质上就是一个"新手入职指南"&#xff0c;让通用 AI 变成某个领域的专家。 目录结构 skill-name/ ├── SKILL.md # 必须&#xff0c;核心文件 └…...

嵌入式系统电源时序控制原理与实现

1. 电源时序控制基础概念在现代电子系统中&#xff0c;多电压域设计已成为常态。一个典型的嵌入式系统可能同时需要1.2V&#xff08;核心逻辑&#xff09;、3.3V&#xff08;外设接口&#xff09;和1.5V&#xff08;特殊功能模块&#xff09;等多种电压。这些电源的上电顺序对系…...

从‘迷失’到‘秒达’:我用PyCharm的‘符号搜索’和‘调用链查看’重构了老项目

从‘迷失’到‘秒达’&#xff1a;我用PyCharm的‘符号搜索’和‘调用链查看’重构了老项目 接手一个缺乏文档的遗留代码库&#xff0c;就像被扔进一座没有地图的迷宫。上周我面对的就是这样一个Python项目——3万行代码&#xff0c;零文档&#xff0c;函数命名随意得像临时起意…...

Nunchaku-flux-1-dev模型服务监控:使用Node.js搭建性能仪表盘

Nunchaku-flux-1-dev模型服务监控&#xff1a;使用Node.js搭建性能仪表盘 你是不是也遇到过这种情况&#xff1f;自己部署的AI模型服务&#xff0c;用着用着突然就变慢了&#xff0c;或者干脆没响应了&#xff0c;用户反馈过来才知道出了问题。等到发现的时候&#xff0c;可能…...

llama-index 数据清洗示例、数据清洗等

文章目录示例数据清洗常见的需要清洗的数据数据清洗知识llama的一小块功能&#xff0c;主文章内容太多了&#xff0c;拆出来单独说下。示例 环境还基于之前的环境。 1、新建python文件clean_demo.py&#xff0c;代码&#xff1a; import os from llama_index.core import Do…...