两两交换链表中的节点
- LeetCode题目链接
- 卡尔老师代码随想录讲解
- 关键点: 这道题目跟翻转链表很相似,但是要求的是两两相邻,即两个相邻节点是一组。我首先想到的就是递归算法,详情看下面代码。卡尔老师提供了非递归的算法,关键点就是加入虚拟头节点,每次都找到要两两交换的节点前一个节点,操作这个节点的后两个节点。
- 代码:
递归算法:
var swap = function (first,second) {
//两者有一个为null则说明此次不需要交换节点了直接返回first
if (!(first && second)) return first
//保存下一个要交换节点的头节点
let tmp = second.next
second.next = first
//交换以后first应该指向下一对两个相邻元素的头节点
first.next = swap(tmp,(tmp ? tmp.next : null))
//交换后第二个节点变为头节点
return second
}
/**
* @param {ListNode} head
* @return {ListNode}
*/
var swapPairs = function(head) {
let first = head
let second = (first ? first.next : null)
return swap(first,second)
};
非递归算法:
var swapPairs = function(head) {
const dummyhead = new ListNode(0,head)
let cur = dummyhead
while(cur.next != null && cur.next.next != null) {
let tmp = cur.next
let tmp1 = cur.next.next
tmp.next = tmp1.next
tmp1.next =tmp
cur.next = tmp1
cur = cur.next.next
}
return dummyhead.next
};
- 注意:
- 题目要求不能只是交换两个相邻节点的值,是针对节点操作的
- 非递归算法时要注意操作前后两个节点时的先后顺序,以免出现指针在一个节点循环
- 复杂度分析:
时间:两种算法时间复杂度都是O( n n n)
空间:递归算法:O( n n n)、非递归算法:O( 1 1 1)