Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100
思路分析:
两两交换,可以从第 0 个结点开始,每两个结点进行处理。
处理过程中,可以额外定义一个新的结点,用于指向交换后头结点。
对于处理中的当前结点:
-
如果当前结点有 Next(下一个结点),则把当前结点的 Next(下一个结点)先放到临时结点变量中,然后将当前结点的 Next(下一个结点)指向 当前结点的 Next(下一个结点)的 Next(下一个结点),再把将临时结点变量的 Next(下一个结点)指向当前结点。
新结点指针的 Next(下一个结点)指向临时结点变量。 -
如果当前结点没有 Next(下一个结点),则将新结点指针的 Next(下一个结点)指向当前结点。
每次处理的最后,需要将处理中的结点指向下一个结点,新结点指针也指向下一个结点。
AC 代码:
golang :
// 两两交换链表中的节点
func swapPairs(head *ListNode) *ListNode {
// 定义一个新的结点链表,用于把整理好的结点挂在上面。
var newHead ListNode
// 新的结点链表的指针,用于记录 整理好的结点的位置
ptr := &newHead
// 目标链表的指针
node := head
for i := 0; node != nil; i++ {
// 当前节点为偶数结点位置时
if i%2 == 0 {
// 如果当前节点的 Next(下一个结点)不为 空时,交换结点
if node.Next != nil {
// 定义临时变量指向当前结节的 Next (下一个结点)
tmp := node.Next
// 当前结节的 Next (下一个结点) 指向 当前结节的 Next (下一个结点)的 Next(下一个结点)
node.Next = node.Next.Next
// 当前结节的 Next (下一个结点)的 Next (下一个结点)设为当前结点
tmp.Next = node
// 挂到新的结点链表上
ptr.Next = tmp
} else {
// 如果当前节点的 Next(下一个结点)不为 空时,
// 将当前节点的 Next(下一个结点)挂到新的结点链表上
ptr.Next = node
}
// 处理下一个结点
node = node.Next
}
ptr = ptr.Next
}
return newHead.Next
}
总结:
做这个题时,一开始没想到如何定义保留整个链表的指针,以致到了最后没有一个指针对应的链表是对的。
最后才想到先定义一个新结点,当做整个结点的头。
应该也可以定义一个头结点变量,在最前面两个结点交换完后,把头结点变量指向交换后的头结点(还没试)。
其实做该题,中间是在 Debug 模式下各种尝试才做出来的。
要是面试的话,可就瞎了。 ~ 囧 ~