[LeetCode解題攻略] 24. Swap Nodes in Pairs

[LeetCode解題攻略] 24. Swap Nodes in Pairs

更新於 發佈於 閱讀時間約 6 分鐘

題目描述

給定一個鏈表,每次交換相鄰的兩個節點,返回交換後的鏈表。要求在不改變節點值的情況下進行節點交換(即直接操作鏈表結構)。

條件

  • 鏈表的長度範圍是 0 <= n <= 100
  • 節點的值範圍是 0 <= Node.val <= 100

範例 1:

Input: head = [1,2,3,4]
Output: [2,1,4,3]
raw-image

範例 2:

Input: head = []
Output: []

範例 3:

Input: head = [1]
Output: [1]

範例 4:

Input: head = [1,2,3]
Output: [2,1,3]

解題思路

解題的核心是理解如何操作鏈表結構來交換節點,而不是僅僅交換節點的值。可以使用以下幾種方法解決該問題:

  1. 遞迴法:以遞迴的方式處理交換,逐步處理剩餘鏈表。
  2. 迭代法:利用指針操作,逐段交換相鄰的節點。

解法一:遞迴法

思路

  1. 如果鏈表為空或只有一個節點,直接返回該鏈表。
  2. 交換當前的兩個節點後,將後續鏈表遞迴處理。
  3. 將處理後的結果鏈接到已交換的節點。

程式碼

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 基本情況:鏈表為空或只有一個節點
if not head or not head.next:
return head

# 交換第一對節點
new_head = head.next
head.next = self.swapPairs(new_head.next)
new_head.next = head

return new_head

時間與空間複雜度

  • 時間複雜度
    每次遞迴處理兩個節點,總共有 n/2 次操作,因此時間複雜度為 O(n),其中 n 是鏈表的節點數。
  • 空間複雜度
    由於使用遞迴,每次遞迴都需要額外的函數調用棧,最深遞迴深度為 n/2,空間複雜度為 O(n)。

解法二:迭代法

思路

  1. 使用虛擬節點(dummy node)作為輔助,方便處理頭節點的交換。
  2. 每次交換相鄰的兩個節點,並更新指針以處理下一對節點。
  3. 最後返回新的頭節點。

程式碼

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 創建一個虛擬節點
dummy = ListNode(0)
dummy.next = head
prev = dummy

# 遍歷鏈表,逐對交換節點
while prev.next and prev.next.next:
first = prev.next
second = first.next

# 交換節點
prev.next = second
first.next = second.next
second.next = first

# 移動 prev 指針到下一對節點前
prev = first

return dummy.next

時間與空間複雜度

  • 時間複雜度
    每次迭代處理兩個節點,總共有 n/2 次操作,因此時間複雜度為 O(n)。
  • 空間複雜度
    迭代過程中使用常數額外空間,空間複雜度為 O(1)。

總結

  1. 遞迴法 適合小型鏈表,程式碼簡潔但可能受到遞迴深度限制。
  2. 迭代法 是處理長鏈表的最佳選擇,時間與空間效率更高。

選擇適合的解法取決於具體場景,迭代法通常是更通用的解法。

avatar-img
追極光的北極熊|軟體工程師的小天地
6會員
115內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
留言
avatar-img
留言分享你的想法!
給定 k 個遞增排序的鏈表,將它們合併成一個遞增排序的鏈表,並返回合併後的鏈表。
給定一個整數 n,請生成所有可能由 n 對括號組成的 有效括號組合。
給定兩個遞增排序的鏈表 list1 和 list2,將它們合併為一個新的 遞增排序 的鏈表,並返回這個新鏈表。新的鏈表應該由這兩個鏈表中的節點組成,而不應創建新的節點。最後回傳合併後的鍊錶的頭節點。
給定一個僅包含字元 '(', ')', '{', '}', '[' 和 ']' 的字串 s,確定輸入字串是否有效。
給定一個Linked list的head,從這個Linked list的末尾刪除第 n 個節點並返回其head。
給定一個包含 n 個整數的陣列 nums,傳回所有唯一的四元組 [nums[a], nums[b], nums[c], nums[d]] 的數組,使得該答案滿足題目的每項要求。
給定 k 個遞增排序的鏈表,將它們合併成一個遞增排序的鏈表,並返回合併後的鏈表。
給定一個整數 n,請生成所有可能由 n 對括號組成的 有效括號組合。
給定兩個遞增排序的鏈表 list1 和 list2,將它們合併為一個新的 遞增排序 的鏈表,並返回這個新鏈表。新的鏈表應該由這兩個鏈表中的節點組成,而不應創建新的節點。最後回傳合併後的鍊錶的頭節點。
給定一個僅包含字元 '(', ')', '{', '}', '[' 和 ']' 的字串 s,確定輸入字串是否有效。
給定一個Linked list的head,從這個Linked list的末尾刪除第 n 個節點並返回其head。
給定一個包含 n 個整數的陣列 nums,傳回所有唯一的四元組 [nums[a], nums[b], nums[c], nums[d]] 的數組,使得該答案滿足題目的每項要求。