[LeetCode][golang] 24. 两两交换链表中的节点

233 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述:

24. 两两交换链表中的节点

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:

image.png

输入: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 模式下各种尝试才做出来的。
要是面试的话,可就瞎了。 ~ 囧 ~