携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
链接: 24. 两两交换链表中的节点
分析
根据题目获取题意
- 链表
- 节点信息包括值和指针,在JavaScript中,空指针为null,链表的尾节点的指针信息为null,所以只需要头指针就可以确定整条链表
- 两两交换相邻的节点
- [1->2->3->4]两两交换过程
- [2->1->3->4]
- [2->1->4->3]
- 两两交换,酱油和醋分别在A瓶和B瓶,让把酱油倒到B瓶,让醋倒到A瓶,此时需要一个空瓶子。链表节点两两交换类似,链表的两两交换需要一个空节点,因此两两交换的时候,是在操作3个变量,脑袋里一定要清楚谁是谁的next,交换之后当前的头指针指向了谁
- [1->2->3->4]两两交换过程
- 链表的遍历
- 链表的遍历可以递归也可以迭代,喜欢用哪种方法就可以用哪种
- 不修改内部的值
- 不要写投机取巧的方法,考察的就是链表节点指针指向
关于递归和迭代
- 递归在运行过程中自己调用自己,把问题分解成多个子问题,子问题的解决思路与原问题的解决思路一样,甚至更简单。递归算法需要有一个出口,即终止条件。
- 迭代是在已知变量通过递推公式不断得到新的值,与普通循环的区别是迭代过程中产生的新的值作为下一次循环计算的初始值。
- 对于本题中的链表遍历来说,递归和迭代都是差不多的,我喜欢用递归的思想,因此AC代码是用递归实现的
代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var swapPairs = function(head) {
if(!head || !head.next) return head;
let a = head
let b = head.next
let c= b.next
b.next = a
a.next = swapPairs(c)
return b
};
总结
- 本题难度定为中等可能因为链表是一种不同于数组的数据结构,只需要改变指针指向,就可以改变数据。
- 对于链表不是很了解的,可以先做一道难度为简单的链表题目, 206. 反转链表,比如把链表[1->2->3->4]翻转成[1<-2<-3<-4],我们只是习惯写成[4->3->2->1],这道题目可以让我们感受到指针的魅力。
- 今天又是有收获的一天。