链表面试题

💓作者简介👏:在校大二迷茫大学生

💖个人主页🎉:小李很执着

💗系列专栏:Leetcode经典题

每日分享:其实要过那条马路并不难,就看谁在对面等你❣️❣️❣️

目录

💝1.876. 链表的中间结点

❣️1.题目 

❣️2.解答:快慢指针法

💝2.21. 合并两个有序链表

❣️1.题目

❣️2.解答 :双指针遍历两个链表

💝3.OR36 链表的回文结构

❣️1.题目

❣️2.解答:快慢指针和链表反转

💝4.138.随机链表的复制

❣️ 1.题目:

❣️2.解答


💝1.876. 链表的中间结点

876. 链表的中间结点icon-default.png?t=N7T8https://leetcode.cn/problems/middle-of-the-linked-list/

❣️1.题目 

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

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

示例 1:


输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 。
示例 2:


输入:head = [1,2,3,4,5,6]
输出:[4,5,6]
解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。

提示:

链表的结点数范围是 [1, 100]
1 <= Node.val <= 100

❣️2.解答:快慢指针法

算法思路:

使用快慢指针,快指针每次移动两步,慢指针每次移动一步。当快指针到达链表末尾时,慢指针正好到达中间位置。

具体实现:

首先定义两个指针 slow 和 fast 都指向链表头节点 head。然后使用 while 循环遍历链表,当快指针 fast 到达链表的末尾或者为空时,遍历结束。在循环过程中,每次快指针移动两步,慢指针移动一步。最终返回慢指针 slow,即为链表的中间节点。

遍历两遍:

第一遍:求出链表的长度

第二遍:长度/2

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

💝2.21. 合并两个有序链表

21. 合并两个有序链表icon-default.png?t=N7T8https://leetcode.cn/problems/merge-two-sorted-lists/

❣️1.题目

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

❣️2.解答 :双指针遍历两个链表

通过使用双指针遍历两个链表,将较小的节点依次加入新链表中。具体实现步骤如下:

  1. 首先判断两个链表中是否有空链表,若有则直接返回不为空的链表。

  2. 定义一个新链表的头指针head和尾指针tail,初始值均为NULL。

  3. 使用while循环遍历list1和list2,比较当前节点的值大小,将较小的节点添加到新链表中。

  4. 当一个链表遍历完后,将另一个链表中剩余的节点全部添加到新链表的尾部。

  5. 返回新链表的头指针head。

需要注意的是,在添加节点到新链表时需要更新尾指针tail。另外,最后返回的是新链表的头指针head,而不是尾指针tail。

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
if(list1==NULL)
return list2;if(list2==NULL)
return list1;
struct ListNode* tail = NULL,*head = NULL;
while(list1 && list2)
{
if(list1->val < list2->val)
{
if(tail == NULL)
{
head = tail = list1;
}
else
{
tail->next = list1;
tail = tail->next;
}
list1 = list1->next;
}
else
{
if(tail == NULL)
{
head = tail = list2;
}
else
{
tail->next = list2;
tail = tail->next;
}
list2 = list2->next;
}
}
if(list1)
tail->next = list1;
if(list2)tail->next = list2;
return head;  
}

💝3.OR36 链表的回文结构

❣️1.题目

描述
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

测试样例:
1->2->2->1
返回:true

❣️2.解答:快慢指针和链表反转

具体思路如下:

  1. 使用快慢指针找到链表的中间节点,如果链表长度是奇数,则中间节点是正中间的那个节点,如果长度是偶数,则中间节点是偏右的那个节点。

  2. 将链表的后半部分进行反转操作。

  3. 分别从链表头和反转后的链表头开始向中间遍历,比较每个节点的值是否相等,如果有不相等的则说明不是回文链表。

  4. 如果整个链表都遍历完了并且每个节点的值都相等,则说明是回文链表。

代码中定义了三个函数:

  1. reverseList:链表反转函数,输入一个链表头节点,返回反转后的链表头节点。

  2. middleNode:快慢指针找中间节点函数,输入链表头节点,返回中间节点。

  3. chkPalindrome:判断是否为回文链表的函数,输入链表头节点,返回是否为回文链表。

class PalindromeList {
public:
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;
}
struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head, *fast = head;while (fast && fast->next) {slow = slow->next;fast = fast->next->next;}return slow;
}
bool chkPalindrome(ListNode* head) {struct ListNode* mid = middleNode(head);struct ListNode* rhead = reverseList(mid);while (head && rhead) {if (head->val != rhead->val)return false;head = head->next;rhead = rhead->next;}return true;
}};

💝4.138.随机链表的复制

138. 随机链表的复制icon-default.png?t=N7T8https://leetcode.cn/problems/copy-list-with-random-pointer/

❣️ 1.题目:

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]

示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

提示:

  • 0 <= n <= 1000
  • -104 <= Node.val <= 104
  • Node.random 为 null 或指向链表中的节点。

❣️2.解答

  1. 在原链表中每个节点的后面插入一个新的节点,新节点的值等于原节点的值,新节点的 next 指针等于原节点的 next 指针。

  2. 复制随机指针:对于原链表中的每个节点 cur,将其新节点 copy 的随机指针指向原节点 cur 的随机指针指向节点的下一个节点。

  3. 分离新旧链表:将新链表的头结点和尾结点初始化为 NULL,然后遍历原链表中的每个节点 cur,将 cur 的新节点 copy 从原链表中分离出来,加入到新链表的尾部。最后,将原链表和新链表断开连接,并将新链表的头结点作为结果返回。

该方法的时间复杂度为 O(n),其中 n 是链表中节点的个数。空间复杂度为 O(n),需要额外的空间存储每个节点的复制品。

struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;while(cur){struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;copy->next = cur->next;cur->next = copy;
//cur = copy->next;cur = cur->next->next;}
cur = head;
while(cur)
{
struct Node* copy = cur->next;
if(cur->random == NULL)
{
copy->random = NULL;
}
else
{
copy->random = cur->random->next;
}
//cur = copy->next;
cur = cur->next->next;
}
struct Node* newhead = NULL,*tail = NULL;
cur = head;
while(cur)
{
struct Node* copy = cur->next;
struct Node* next = copy->next;
if(tail == NULL)
{
newhead = tail = copy;
}
else
{
tail->next = copy;
tail = tail->next;
}
cur->next = next;
cur = next;
}
return newhead;}

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

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

相关文章

error: C3867: “MainWindow::copyFileCallBack”: 非标准语法;请使用 ““

error: C3867: “MainWindow::copyFileCallBack”: 非标准语法&#xff1b;请使用 “&” 这时候我们按照提示将t.testFun前面加上&又会出现error C2276: “&”: 绑定成员函数表达式上的非法操作&#xff0c; 解决 在函数前面加上static声明

ISP 处理流程

#灵感# 摆烂时间太长了&#xff0c;感觉知识忘光光了。重新学习&#xff0c;常学常新。 因为公司文档都不让摘抄、截取&#xff0c;所以内容是工作的一些自己记录和网络内容&#xff0c;不对的欢迎批评指正。 1、ISP概述 ISP是Image Signal Processor 的简称&#xff0c;也就…

nodejs+vue公益帮学网站的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

在当今高度发达的信息中&#xff0c;信息管理改革已成为一种更加广泛和全面的趋势。为确保中国经济的持续发展&#xff0c; 如何用方便快捷的方式使管理者在广阔的数据海洋里面查询、存储、管理和共享有效的数据信息&#xff0c;对我们的学习&#xff0c;工作和生活具有重要的现…

视频推拉流EasyDSS直播点播平台获取指定时间快照的实现方法

视频推拉流直播点播系统EasyDSS平台&#xff0c;可提供流畅的视频直播、点播、视频推拉流、转码、管理、分发、录像、检索、时移回看等功能&#xff0c;可兼容多操作系统&#xff0c;在直播点播领域具有广泛的场景应用。为了便于用户集成、调用与二次开发。 今天我们来介绍下在…

C#中.NET Framework4.8 Windows窗体应用通过EF访问数据库并对数据库追加、删除记录

目录 一、应用程序设计 二、应用程序源码 三、生成效果 前文作者发布了在.NET Framework4.8 控制台应用中通过EF访问已有数据库&#xff0c;事实上在.NET Framework4.8 Windows窗体应用中通过EF访问已有数据库也是一样的。操作方法基本一样&#xff0c;数据库EF模型和上下文…

STM32 I2C详解

STM32 I2C详解 I2C简介 I2C&#xff08;Inter IC Bus&#xff09;是由Philips公司开发的一种通用数据总线 两根通信线&#xff1a; SCL&#xff08;Serial Clock&#xff09;串行时钟线&#xff0c;使用同步的时序&#xff0c;降低对硬件的依赖&#xff0c;同时同步的时序稳定…

【kafka】windows安装启动

1.zookeeper的安装与启动 快速打开window powershell&#xff1a; windowx&#xff0c;选 2.kafka下载 —注意kafka和zookeeper需要版本匹配 安装路径 注意&#xff0c;kafka安装目录不能有空格。文件下载到&#xff1a; D:\Program_Files\kafka_2.12-3.6.0新建logs文件 修改c…

JavaScript中的原型和原型链

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 原型和原型链是JavaScript中一个重要且常常被误解的概念。它们在理解对象、继承和属性查找时扮演着关键的角色。 1…

基于单片机的农田智能驱鼠装置(论文+源码)

1.系统设计 在基于单片机的农田智能驱鼠装置设计中&#xff0c;分为四个模块电源模块、感应模块、控制模块和音频模块。电源模块为整个系统提供5v的直流电源&#xff0c;支撑驱鼠器的整体运作。热释电红外感应模块用来感应鼠类的入侵。控制模块则采用STC89C52单片机编程进行时…

unity 使用Vuforia扫描实体物体交互

文章目录 前言一、Vuforia是什么&#xff1f;二、Unity导入Vuforia1.去Unity - Windows – Asset Store&#xff0c;搜vuforia engine&#xff0c;添加到我的资源2.从 Unity 的菜单 Assets -> Import package -> Custom Package 导入脚本&#xff0c;添加 Vuforia Engine…

【python 生成器 面试必备】yield关键字,协程必知必会系列文章--自己控制程序调度,体验做上帝的感觉 2

这篇文章要解决的问题&#xff1a;How to Pass Value to Generators Using the “yield” Expression in Python ref:https://python.plainenglish.io/yield-python-part-ii-e93abb619a16 1.如何传值 yield 是一个表达式&#xff01;&#xff01;&#xff01;&#xff01; yi…

excel中的OFFSET函数

介绍 OFFSET函数是确定从基点出发移动后的引用区域。它有5个参数&#xff1a; 第1个参数是引用的参考基点区域第2个参数是移动的行数&#xff0c;正数代表向下移动的行数&#xff0c;负数代表向上移动的行数第3个参数是移动的列数&#xff0c;正数代表向右移动的列数&#xf…