算法(附思维导图+全部解法)300题24两两交换链表中的节点
零 标题:算法(leetode,附思维导图 + 全部解法)300题之(24)两两交换链表中的节点
一 题目描述
二 解法总览(思维导图)
三 全部解法
1 方案1
1)代码:
// 方案1 “简单、直观法”(本质就是“化归” —— 把不熟悉的变成熟悉的)。 // 1)遍历链表,依次将所有节点的值存入 数组 resArr 里。 // 2)遍历 resArr ,间隔(step、步骤)为2、相邻的奇偶位置值互换。 // 3)再次遍历 resArr ,依次将所有元素存入新链表中。 // 4)返回结果 resHead 。 var swapPairs = function(head) { let resArr = []; // 1)遍历链表,依次将所有节点的值存入 数组 resArr 里。 while (head) { resArr.push(head.val); head = head.next; } const l = resArr.length; // 2)遍历 resArr ,间隔(step、步骤)为2、相邻的奇偶位置值互换。 for (let i = 0; i <= l - 2; i += 2) { const j = i + 1; if (resArr[j] !== undefined) { [resArr[i], resArr[j]] = [resArr[j], resArr[i]]; } } let resHead = null, resHead = null; // 3)再次遍历 resArr ,依次将所有元素存入新链表中。 for (let i = 0; i < l; i++) { if (i === 0) { resHead = resHead = new ListNode(resArr[i]); } else { resHead.next = new ListNode(resArr[i]); resHead = resHead.next; } } // 4)返回结果 resHead 。 return resHead; };
2 方案2
1)代码:
// 方案2 “递归”。 // 核心代码(即递归主体): // let one = head, // two = one.next, // three = two.next; // two.next = one; // one.next = swapPairs(three); // return two; var swapPairs = function(head) { // 1)递归出口。 // 若 节点数小于2(即 此时 head.next.next 肯定不存在)时, // 则 返回当前传入的头结点 —— head 即可。 if (head === null || head.next === null) { return head; } // 2)递归主体 // 2.1)声明 one(head)、two(one.next)、three(two.next) 3个节点 let one = head, two = one.next, three = two.next; // 2.1)核心处理: // two.next = one; one.next = swapPairs(three); two.next = one; one.next = swapPairs(three); // 2.3)返回此时的 two 节点 —— 共上一层调用时的 one.next 赋值用。 return two; // 参考: // 1)https://leetcode-cn.com/problems/swap-nodes-in-pairs/solution/liang-liang-jiao-huan-lian-biao-zhong-de-jie-di-91/ }
3 方案3
1)代码:
// 方案3 “迭代法”。TODO:较复杂,后续需加上详细的思路(含图文等)与注释。 // 注意:“其实就是方案2的迭代实现”。 // 思路: // 1)创建哑结点 dummyHead,令 dummyHead.next = head。令 temp 表示当前到达的节点,初始时 temp = dummyHead。每次需要交换 temp 后面的两个节点。 // 如果 temp 的后面没有节点或者只有一个节点,则没有更多的节点需要交换,因此结束交换。否则,获得 temp 后面的两个节点 node1 和 node2,通过更新节点的指针关系实现两两交换节点。 // 2)具体而言,交换之前的节点关系是 temp -> node1 -> node2,交换之后的节点关系要变成 temp -> node2 -> node1,因此需要进行如下操作: // temp.next = node2 // node1.next = node2.next // node2.next = node1 // 3)完成上述操作之后,节点关系即变成 temp -> node2 -> node1。再令 temp = node1,对链表中的其余节点进行两两交换,直到全部节点都被两两交换。 // 4)两两交换链表中的节点之后,新的链表的头节点是 dummyHead.next,返回新的链表的头节点即可。 var swapPairs = function(head) { // 1)dummyHead 为哑结点(辅助节点)。 const dummyHead = new ListNode(0); dummyHead.next = head; let temp = dummyHead; // 2)核心处理。 while (temp.next !== null && temp.next.next !== null) { const node1 = temp.next; const node2 = temp.next.next; temp.next = node2; node1.next = node2.next; node2.next = node1; temp = node1; } // 3)返回结果 dummyHead.next 。 return dummyHead.next; // 参考: // 1)https://leetcode-cn.com/problems/swap-nodes-in-pairs/solution/liang-liang-jiao-huan-lian-biao-zhong-de-jie-di-91/ }
四 更多
1 GitHub - LeetCode项目仓库
0)本项目地址: https://github.com/CYBYOB/algorithm-leetcode 。 目标、愿景: 让每个人都能拥有一定的算法能力、以应对面试中(会举一反三的同学还可以将其融入自己的肌肉和血液,甚至能够赋能于公司的业务和技术)的算法。 1)项目的根目录下的 README.md 文件, 可以帮您快速查阅每1道题的来源、难度、所有的题解方案等。 2)而每个题解(即 index.md 文件)中, 还将附带题目描述、所有的题解方案的思维导图( .xmind 文件)、思路和技巧等。 3)每种题解方案都有详细的注释, 通过“数字步骤”将抽象的算法逻辑、 清晰和有层次的展示于您的面前。 可以说是, 开箱即用~ 4)所有的题解方案都是经过作者1人之手, 故代码风格及其统一。 一旦阅读达到一定量后, 后续将大大提升您的阅读速度 —— “正所谓、量变引起质变”。 5)本人每周仍在不断的更新 —— 保证每周都有新的题目、题解方案刺激着您的神经 和 刷题欲望。 欢迎对算法感兴趣的同学加入我们的社群。 QQ群: 933919972 ; 作者QQ: 1520112971 ; 作者VX: c13227839870(可拉您进群、一起学习与交流~) 。
2 作者标签
1)“伪全栈工程师,主攻前端,偶尔写点后端”。 2)2019年的微信小程序应用开发赛 - 全国三等奖; 2019CODA比赛 - 前 17/211 强 且 荣获“优秀团队”称号 等。 3)“半自媒体人”, 在校期间、个人公众号(IT三少。新自媒体(公众号)号: 码农三少 ) 在半年内实现了0到5.8K+的粉丝增长等。#互联网求职##学习路径#