两两交换链表中的结点
思路:虽然可以通过改结点值或者在数组中交换然后再转回链表的方法进行,但是这题题目不允许那么干
还是递归,只不过每次移动两个位置
对于问题 "两两交换链表中的节点",我们可以通过调整节点的 next 指针来交换每对相邻节点。这可以通过迭代或递归的方式实现。由于迭代方法通常更直观,这里将主要介绍如何使用迭代方法解决此问题:
- 创建哨兵节点:
-
- 在链表的开头创建一个哨兵节点 (dummy),其 next 指针指向链表的头节点。这可以帮助简化边界条件,尤其是当链表很短时。
- 初始化指针:
-
- 使用一个指针 prev 来跟踪当前要交换的两个节点的前一个节点。初始时,prev 指向哨兵节点。
- 交换节点:
-
- 在每次循环中,如果 prev 后面有至少两个节点(即 prev.next 和 prev.next.next 都不为空),则交换这两个节点。
- 设 first = prev.next 和 second = prev.next.next,交换 first 和 second,更新 prev 的 next 指针指向 second,使得 first.next 指向 second.next,然后将 second.next 指向 first。
- 移动指针:
-
- 将 prev 移动两个节点,为下一对要交换的节点做准备。
- 返回结果:
-
- 返回哨兵节点的 next,它现在指向新的链表头。
代码
func swapPairs(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
dummy := &ListNode{
Next: head,
}
prev := dummy
//注意边界条件
for prev != nil && prev.Next != nil && prev.Next.Next != nil {
//交换两个结点
leftNode := prev.Next
rightNode := prev.Next.Next
prev.Next = rightNode
next := rightNode.Next //这个是之后的一串的位置
rightNode.Next = leftNode
leftNode.Next = next
//移动两个结点
prev = prev.Next.Next
}
return dummy.Next
}