From 9fbdb32bcfe8f921d872ad4826076f2bd2bd8ad6 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Wed, 12 May 2021 21:14:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=93=BE=E8=A1=A8=E4=B8=93?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +- .../0024.两两交换链表中的节点.md | 100 ++++++++++++++++++ 2 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 problems/0024.两两交换链表中的节点.md diff --git a/README.md b/README.md index df397457..276c8313 100644 --- a/README.md +++ b/README.md @@ -116,10 +116,11 @@ 1. [关于链表,你该了解这些!](./problems/链表理论基础.md) 2. [链表:听说用虚拟头节点会方便很多?](./problems/0203.移除链表元素.md) 3. [链表:一道题目考察了常见的五个操作!](./problems/0707.设计链表.md) -4. [链表:听说过两天反转链表又写不出来了?](./problems/0206.翻转链表.md) -5. [链表:删除链表的倒数第 N 个结点](./problems/0019.删除链表的倒数第N个节点.md) -5. [链表:环找到了,那入口呢?](./problems/0142.环形链表II.md) -6. [链表:总结篇!](./problems/链表总结篇.md) +4. [链表:听说过两天反转链表又写不出来了?](./problems/0206.翻转链表.md) +5. [链表:两两交换链表中的节点](./problems/0024.两两交换链表中的节点.md) +6. [链表:删除链表的倒数第 N 个结点](./problems/0019.删除链表的倒数第N个节点.md) +7. [链表:环找到了,那入口呢?](./problems/0142.环形链表II.md) +8. [链表:总结篇!](./problems/链表总结篇.md) ## 哈希表 diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md new file mode 100644 index 00000000..aa284279 --- /dev/null +++ b/problems/0024.两两交换链表中的节点.md @@ -0,0 +1,100 @@ + +
+欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
+ +## 24. 两两交换链表中的节点 + +给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 + +你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 + + + + +## 思路 + +这道题目正常模拟就可以了。 + +建议使用虚拟头结点,这样会方便很多,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理。 + +对虚拟头结点的操作,还不熟悉的话,可以看这篇[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)。 + +接下来就是交换相邻两个元素了,**此时一定要画图,不画图,操作多个指针很容易乱,而且要操作的先后顺序** + +初始时,cur指向虚拟头结点,然后进行如下三步: + + + +操作之后,链表如下: + + + +看这个可能就更直观一些了: + + + + +对应的C++代码实现如下: (注释中详细和如上图中的三步做对应) + +```C++ +class Solution { +public: + ListNode* swapPairs(ListNode* head) { + ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点 + dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作 + ListNode* cur = dummyHead; + while(cur->next != nullptr && cur->next->next != nullptr) { + ListNode* tmp = cur->next; // 记录临时节点 + ListNode* tmp1 = cur->next->next->next; // 记录临时节点 + + cur->next = cur->next->next; // 步骤一 + cur->next->next = tmp; // 步骤二 + cur->next->next->next = tmp1; // 步骤三 + + cur = cur->next->next; // cur移动两位,准备下一轮交换 + } + return dummyHead->next; + } +}; +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(1)$ + +## 拓展 + +**这里还是说一下,大家不必太在意力扣上执行用时,打败多少多少用户,这个统计不准确的。** + +做题的时候自己能分析出来时间复杂度就可以了,至于力扣上执行用时,大概看一下就行。 + +上面的代码我第一次提交执行用时8ms,打败6.5%的用户,差点吓到我了。 + +心想应该没有更好的方法了吧,也就O(n)的时间复杂度,重复提交几次,这样了: + + + +力扣上的统计如果两份代码是 100ms 和 300ms的耗时,其实是需要注意的。 + +如果一个是 4ms 一个是 12ms,看上去好像是一个打败了80%,一个打败了20%,其实是没有差别的。 只不过是力扣上统计的误差而已。 + + +## 其他语言版本 + + +Java: + + +Python: + +Go: + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) +* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) +