顺序表链表OJ题(1)——【LeetCode】

W...Y的主页 😊

代码仓库分享 💕


 前言:

今天我们来回顾一下顺序表与链表,针对这一块我们也有许多OJ题目供大家参考。当我们学习完顺序表链表后避免不了一些习题的练习,这样才能巩固我们学习的内容。

话不多说,我们开始进入OJ习题训练!!!

【leetcode 27.移除元素】 

OJ链接

给你一个数组 和一个值 ,你需要原地移除所有数值等于 的元素,并返回移除后数组的新长度。numsvalval

不要使用额外的数组空间,你必须仅使用 额外空间并原地修改输入数组O(1)

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

题目函数接口 nums:给定数组内容。numsSize:数组长度大小。val:移除元素。


题目要求原地删除数据,不能创建任何数组,这就会使原本简单的题变复杂。那我们应该怎么办呢?

首先我们最先想到的方法是遍历数组,遇到需要删除的内容就将数组后面的元素向前挪动一位,让其覆盖。但是这种方法非常”危险“,有可能导致数组越界,也有可能删除遗漏。所以这不是个好方法。

接下来将一个比较新颖且简单的方法:

双指针: 创建两个指针变量src与dst,两个指针全部指向数组开头。如果src指向的内容不是val,将src的内容赋值给dst,然后src与dst全部向后挪动一位。反之如果src指向的内容为val,dst保持原来的位置不动,src向后挪动一位。直至src指向数组的末尾结束。

 这个方法即保证没有创建任何数组空间复杂度为O(1),也优化了暴力遍历法中时间复杂度,从O(n^2)->O(n)。

代码展示:

nt removeElement(int* nums, int numsSize, int val){int ret = 0;int valp = 0;int n = numsSize;while(ret < numsSize){if(nums[ret] != val){nums[valp++] = nums[ret++];}elseret++;}return valp;
}

【leetcode 26.删除有序数组中的重复项】

OJ链接 

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

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k 。

判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案int k = removeDuplicates(nums); // 调用assert k == expectedNums.length;
for (int i = 0; i < k; i++) {assert nums[i] == expectedNums[i];
}

如果所有断言都通过,那么您的题解将被通过

题目函数接口: nums:升序数组。numsSize:数组中元素个数。


思路:快慢双指针

分析:创建两个指针变量fast与slow

如果两个指针指向内容全部相同,fast向后挪动一位slow不变。

如果两个指针指向不同内容,先让slow向后移动一位,再将fast指向的内容赋值给slow,再将fast向后移动一位即可。

等到fast指向数组末尾时,循环结束!

代码演示: 

int removeDuplicates(int* nums, int numsSize){int fast = 1;int slow = 0;int n = numsSize;while(fast < n){if(nums[fast] != nums[slow]){slow++;nums[slow] = nums[fast];}else{fast++;}}return slow+1;}

leetcode 88.合并两个有序数组】 

OJ链接

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

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

题目接口函数: 

nums1与nums2:两个非递减数组。nums1Size:nums1数组大小。nums2Size:nums2数组大小。m:nums1数组有效元素个数。n:nums2数组有效元素个数。


其实我们可以直接将两个数组进行归并,然后进行qsort排序直接完成。但是效率太低了,qsort函数底层原理为快速排序法,时间复杂度太高。

那有没有什么时间复杂度低的解法呢?

这道题本来可以两个数组进行比较,再开辟一个数组,两个数组元素进行比较,谁比较小就尾插到新数组中去。

但是这个题比较特殊,nums1开辟的空间比较大,可以放下两个数组的所有内容,所以我们必须将排序好的数组放入nums1中为了保证时间复杂度为O(m+n)。

但是我们可以使用这种方法的变形(三指针)。

解法:我们可以倒着比较,取大的依次从后往前插入。 创建三个指针,一个指向nums2数组末尾处,一个指向nums1有效元素末尾,还有一个指向nums1数组末尾处。

然后我们进行比较即可: 注意当end1与end2全部结束才可以结束循环,否则会有问题。

举例:num1:【5,6,7,0,0,0】,num2:【2,5,6】

 代码展示:

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

【leetcode 206.反转链表】

OJ链接

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

 题目接口函数:

head:链表头节点


我们在反转数组时,只需要两个指针一个指向头,一个指向尾进行交换即可,最后指向中间即可结束。但是单链表没有数组的特性,不能进行逆向读取,所以这个方法行不通。

现在提供两种方法:

方法一:创建3个指针n1、n2、n3分别指向NULL、head、head->next。标记好三个位置即可进行链表反转。 让n2->next指向n1,然后n1=n2、n2=n3、n3=n3->next即可

一直循环直到n3指向NULL时循环停止结束。

代码演示: 

struct ListNode* reverseList(struct ListNode* head){struct ListNode* a = NULL;struct ListNode* b = head;struct ListNode* c = NULL;if(b)c = b->next;if(head){while(c){a = b;b = c;c = b->next;b->next = a;}head->next = NULL;return b;}elsereturn head;

 我们考虑问题就必须全面,如果链表中只有一个数则返回头指针head即可。

(头插法)方法二:

创建一个新链表头newhead,将旧链表元素挨个反向插入newhead中即可。

 

上述就是操作流程图!!!

代码演示:

struct ListNode* reverseList(struct ListNode* head){ 
struct ListNode* cur = head;struct ListNode*  newhead = NULL;while(cur){struct ListNode* next = cur->next;cur->next = newhead;newhead = cur;cur = next;}return newhead;}

【leetcode 203.移除链表元素】

OJ链接

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。 

 题目接口函数:

head:链表头节点。val:删除目标数


思路分析:移除目标元素,我们就要遍历链表进行查找。创建两个指针prev与cur,prev永远指向cur前一个节点,用来记录。

当cur遇到目标数时,我们就可以使用prev->next =cur->next,将目标数删除。直至cur指向NULL结束。

整体思路如下:

 虽然看上去很简单,但是这种题的“极端”情况非常多。我们必须把这些特殊情况考虑清楚再去写程序才能保证万无一失。

如果遇到上述情况,使用prev->next =cur->next就不实用了,程序就会出错。那我们应该怎么办呢?

我们应该在使用prev->next =cur->next时就先把元素为val的干掉,让head指向不是val的元素。 下面是代码演示:

struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode* prev = NULL, *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;
}

还有一种思路更清晰的方法:

创建一个新的头节点newhead,让cur遍历链表,把元素内容不是val的挪下来与newhead链接即可。

这样的思路更清晰,空间复杂度对于之前方法一没有改变,但是时间复杂度增加了。因为在newhead尾插时要找尾节点。我们可以增加一个尾指针指向newhead链表的尾节点,这样就可以优化时间复杂度。

代码演示:

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*der = cur;cur = cur->next;free(der);}else{if(tail == NULL){newhead = tail = cur;}else{tail->next = cur;tail = tail->next;}cur = cur->next;}if(tail){tail->next = NULL;}}return newhead;
}

 代码中有很多极端问题需要大家去想清楚,在这里就不过多讲述了,不懂可以私信我!!!

【leetcode 876.链表的中间节点】

OJ链接 

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

题目函数接口:

head:目标链表的头节点。


分析题目:这道题我们可以使用最原始的方法进行,先将链表遍历一遍求出链表长度,然后再次进行循环找出中间值即可。

但是有些公司面试会有题目限制要求,只让我们遍历一遍找出中间值。那我们应该怎么做呢?

(快慢指针):

我们创建两个指针变量slow与fast指向链表的头节点,slow一次只移动一个节点,而fast指针一次移动两个节点。当fast指向NULL时,我们的slow节点顺理成章的就找到了中间节点。

这种类型的题目我们就可以利用速度差来达到题目要求!

代码演示: 

struct ListNode* middleNode(struct ListNode* head){struct ListNode* fast = head;struct ListNode* slow = head;while(fast&&fast->next){fast = fast->next->next;slow = slow->next;}return slow;
}

以上是本次全部内容,有错误或不同见解的希望与博主进行沟通交流,博主会继续努力将更好的博客内容带给大家,你们的三连是对博主最大的支持!!! ❤️❤️

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

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

相关文章

回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效…

安防监控视频平台EasyCVR视频汇聚平台和税务可视化综合管理应用方案

一、方案概述 为了确保税务执法的规范性和高效性&#xff0c;国家税务总局要求全面推行税务系统的行政执法公示制度、执法全过程记录制度和重大执法决定法制审核制度。为此&#xff0c;需要全面推行执法全过程记录制度&#xff0c;并推进信息化建设&#xff0c;实现执法全过程的…

HAproxy+keepalived高可用配置搭建

目录 一、概述 &#xff08;一&#xff09;简介 &#xff08;二&#xff09;核心功能 &#xff08;三&#xff09;关键特性 &#xff08;四&#xff09;应用场景 二、安装 1&#xff09;拓补图 2&#xff09;配置 &#xff08;一&#xff09;内核配置 &#xff08;二…

几种在JavaScript中创建对象的方式!

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 字面量方式⭐ 构造函数方式⭐ Object.create()方式⭐ 工厂函数方式⭐ ES6类方式⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门…

【硬件设计】硬件学习笔记一--元器件的介绍与选型

硬件学习笔记一--元器件的选型 一、电阻1.1 电阻的分类1.2 电阻的选型 二、电容2.1 陶瓷电容2.2 钽电容2.3 铝电解电容2.4 电容选型 三、电感3.1 定义与介绍3.2 电感的分类3.3 电感的参数 四、磁珠4.1 磁珠的介绍4.2 磁珠的参数 五、二极管5.1 定义5.2 稳压管5.3 肖特基二极管5…

BDA初级分析——可视化基础

一、可视化的作用 数据可视化——利用各种图形方式更加直观地呈现数据的过程 可视化的作用 1、更快地理解数据&#xff0c;找出数据的规律和异常 2、讲出数据背后的故事&#xff0c;辅助做出业务决策 3、给非专业人士提供数据探索的能力 数据分析问题如何通过可视化呈现&am…

Orchestrator介绍二 自身高可用性方案

目录 获得 HA 的方法 一 没有高可用性 &#xff08;No high availability&#xff09; 使用场景 架构组成 架构图 二 半高可用性&#xff08;Semi HA&#xff09; 三 基于共享数据库后端高可用&#xff08;HA via shared backend&#xff09; 四 基于Raft协议高可用 五…

Tableau可视化入门实践-2

目录 折线图1.导入excel文件数据2.建立折线图并添加标签 双轴折线图 折线图 1.导入excel文件数据 2.建立折线图并添加标签 双轴折线图 行标签拖进两个度量建立上下两个折线图 在第二个折线图纵轴&#xff0c;右键选择“双轴”

【mysql】MySQL服务无法启动 NET HELPMSG 3534

MySQL服务无法启动 NET HELPMSG 3534 错误描述寻找原因解决方法 错误描述 mysql版本&#xff1a;8.1.0 mysql安装成功之后&#xff0c;使用net start mysql来启动mysql&#xff0c;然后出现了报错 MySQL服务无法启动 NET HELPMSG 3534 寻找原因 1、在cmd中&#xff0c;进入…

JWT-Token

一、JWT 需要在 HTTP 这种无状态的机制下&#xff0c;记录下&#xff08;标识&#xff09;出来是不是连续&#xff08;逻辑上的连续&#xff09;的请求。 思路&#xff1a;如果多次请求&#xff0c;携带了相同的标识型数据&#xff0c;则认为是逻辑上连续的。这个标识&#xff…

数据结构(Java实现)LinkedList与链表(下)

** ** 结论 让一个指针从链表起始位置开始遍历链表&#xff0c;同时让一个指针从判环时相遇点的位置开始绕环运行&#xff0c;两个指针都是每次均走一步&#xff0c;最终肯定会在入口点的位置相遇。 LinkedList的模拟实现 单个节点的实现 尾插 运行结果如下&#xff1a; 也…

构建 NodeJS 影院预订微服务并使用 docker 部署(04/4)

一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 我们前几章的快速回顾 第一篇文章介绍了微服务架构模式&#xff0c;并讨论了使用微服务的优缺点。第二篇…

MacOS软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 MacOS是一种由苹果公司开发的操作系统&#xff0c;专门用于苹果公司的计算机硬件。它被广泛用于创意和专业应用程序&#xff0c;如图像设计、音频和视频编辑等。以下是关于MacOS的详细介绍。 1、MacOS的历史和演变 MacOS最初于…

Linux 计算机网络基础概论

一、网络基本概念 1、网络 网络是由若干节点和连接这些结点的链路组成&#xff0c;网络中的结点可以是计算机、交换机、路由器等设备。通俗地说就是把不同的主机连接起来就构成了一个网络&#xff0c;构成网路的目的是为了信息交互、资源共享。 网络设备有&#xff1a;交换机…

ctfshow-web-红包题第六弹

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 首先跑一下字典&#xff0c;这里用的dirmap,可以看到有一个web.zip 下载下来之后发现是一个网站备份&#xff0c;备份的是check.php.bak 然后接着看&#xff0c;可以看到这里不太可能是sql注入&#xff0c;有…

k8s service (三)

K8s service (三) LoadBalancer类型的Service LoadBalancer和NodePort其实是同一种方式&#xff0c;目的都是向外暴露一个端口&#xff0c;区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备&#xff0c;而这个设备需要外部环境支持的&#xff0c;外部服务发送到这…

excel 分组排序

excel中会遇到对不同分组数据进行排序&#xff0c;比如对于不同班级里的学生按照分数高低进行升序排序&#xff0c;可以采用如下公式 SUMPRODUCT((A$2:A$12A2)*(C$2:C$12>C2))1 如果需要 进行降序排序&#xff0c;将公式中的大于号替换为小于号即可

Cinema 4D软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Cinema 4D&#xff08;简称C4D&#xff09;是由德国Maxon Computer公司开发的一款三维动画渲染和建模软件&#xff0c;广泛应用于影视、广告、工业设计等领域。C4D因其高效率、易用性和强大的功能而受到广大设计师和艺术家的青睐…

vue 实现word文档页面内预览docx-preview 和 vue-office

1.先下载引入 npm i docx-preview --save import { renderAsync } from docx-preview;2.使用 fetch(url) .then((response) > {let docData response.blob(); //将文件转换成bolb形式//选择要渲染的元素let childRef document.getElementsByClassName("childRef&qu…

SQL Server软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 SQL Server是一种关系型数据库管理系统&#xff0c;由美国微软公司开发。它被设计用于存储、管理和查询数据&#xff0c;被广泛应用于企业级应用、数据仓库和电子商务等场景。 以下是SQL Server软件的主要特点和功能&#xff1…