代码随想录拓展day4 143.重排链表;141. 环形链表;面试题 02.07. 链表相交
创始人
2024-05-01 15:34:42
0

代码随想录拓展day4 143.重排链表;141. 环形链表;面试题 02.07. 链表相交

关于链表的一些应用,基本都用到了快慢指针的思路。对于单链表来说,确定边界,也就是遍历时的终止条件非常重要。

143.重排链表

143. 重排链表 - 力扣(Leetcode)

不用额外空间的方法还是比较难的,而且还涉及到了很多coding细节的问题,这里注意要用count的奇偶来判断下一个插入的节点。

思路

本篇将给出三种C++实现的方法

  • 数组模拟
  • 双向队列模拟
  • 直接分割链表

方法一

把链表放进数组中,然后通过双指针法,一前一后,来遍历数组,构造链表。

代码如下:

class Solution {
public:void reorderList(ListNode* head) {vector vec;ListNode* cur = head;if (cur == nullptr) return;while(cur != nullptr) {vec.push_back(cur);cur = cur->next;}cur = head;int i = 1; // 注意,head在最开始已经放进数组了,所以下标i从1开始int j = vec.size() - 1;  // i j为之前前后的双指针int count = 0; // 计数,偶数去后面,奇数取前面while (i <= j) {if (count % 2 == 0) {cur->next = vec[j];j--;} else {cur->next = vec[i];i++;}cur = cur->next;count++;}cur->next = nullptr; // 注意结尾}
};

方法二

把链表放进双向队列,然后通过双向队列一前一后弹出数据,来构造新的链表。这种方法比操作数组容易一些,不用双指针模拟一前一后了

class Solution {
public:void reorderList(ListNode* head) {deque que;ListNode* cur = head;if (cur == nullptr) return;while(cur->next != nullptr) {que.push_back(cur->next); // 第一个放进去的是head->nextcur = cur->next;}cur = head;int count = 0; // 计数,偶数去后面,奇数取前面ListNode* node;while(que.size()) {if (count % 2 == 0) {node = que.back();que.pop_back();} else {node = que.front();que.pop_front();}count++;cur->next = node;cur = cur->next;}cur->next = nullptr; // 注意结尾}
};

方法三

将链表分割成两个链表,然后把第二个链表反转,之后在通过两个链表拼接成新的链表。

如图:

在这里插入图片描述

这种方法,比较难,平均切割链表,看上去很简单,真正代码写的时候有很多细节,同时两个链表最后拼装整一个新的链表也有一些细节需要注意!

代码如下:

class Solution {
private:// 反转链表ListNode* reverseList(ListNode* head) {ListNode* temp; // 保存cur的下一个节点ListNode* cur = head;ListNode* pre = NULL;while(cur) {temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->nextcur->next = pre; // 翻转操作// 更新pre 和 cur指针pre = cur;cur = temp;}return pre;}public:void reorderList(ListNode* head) {if (head == nullptr) return;// 使用快慢指针法,将链表分成长度均等的两个链表head1和head2// 如果总链表长度为奇数,则head1相对head2多一个节点ListNode* fast = head;ListNode* slow = head;while (fast && fast->next && fast->next->next) {fast = fast->next->next;slow = slow->next;}ListNode* head1 = head;ListNode* head2;head2 = slow->next;slow->next = nullptr;// 对head2进行翻转head2 = reverseList(head2);// 将head1和head2交替生成新的链表headListNode* cur1 = head1;ListNode* cur2 = head2;ListNode* cur = head;cur1 = cur1->next;int count = 0; // 偶数取head2的元素,奇数取head1的元素while (cur1 && cur2) {if (count % 2 == 0) {cur->next = cur2;cur2 = cur2->next;} else {cur->next = cur1;cur1 = cur1->next;}count++;cur = cur->next;}if (cur2 != nullptr) { // 处理结尾cur->next = cur2;}if (cur1 != nullptr) {cur->next = cur1;}}
};

141. 环形链表

141. 环形链表 - 力扣(Leetcode)

快慢指针的一个应用。同时哈希表也可以解决这个问题,但是需要额外的空间。

思路

可以使用快慢指针法, 分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。

为什么fast 走两个节点,slow走一个节点,有环的话,一定会在环内相遇呢,而不是永远的错开呢?

首先第一点: fast指针一定先进入环中,如果fast 指针和slow指针相遇的话,一定是在环中相遇,这是毋庸置疑的。

那么来看一下,为什么fast指针和slow指针一定会相遇呢?

可以画一个环,然后让 fast指针在任意一个节点开始追赶slow指针。

会发现最终都是这种情况, 如下图:

在这里插入图片描述

fast和slow各自再走一步, fast和slow就相遇了

这是因为fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。

动画如下:

在这里插入图片描述

C++代码如下

class Solution {
public:bool hasCycle(ListNode *head) {ListNode* fast = head;ListNode* slow = head;while(fast != NULL && fast->next != NULL) {slow = slow->next;fast = fast->next->next;// 快慢指针相遇,说明有环if (slow == fast) return true;}return false;}
};

或者使用哈希表的方法,把所有遇到过的节点都加入表中,如果有节点重复出现了,因为是单链表,那一定是链表中有环了。

class Solution {
public:bool hasCycle(ListNode *head) {unordered_set set;ListNode* cur = head;while(cur){if(set.find(cur) != set.end()){return true;} else {set.insert(cur);}cur = cur->next;}return false;}
};

面试题 02.07. 链表相交

面试题 02.07. 链表相交 - 力扣(Leetcode)

旧题目复习,依然是快慢指针的应用,同时用哈希表也可以解决。记住重点是单链表相交结尾必相同。

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...