Python編程題49--兩兩交換鏈表中的節點

題目

給定一個鏈表,請在不修改節點內部值的情況下,兩兩交換其中相鄰的節點,並返回交換後鏈表的頭節點。

例如:

原鏈表轉換爲列表:[1, 2, 3, 4]
最終的鏈表轉換爲列表:[2, 1, 4, 3]

原鏈表轉換爲列表:[1, 2, 3, 4, 5]
最終的鏈表轉換爲列表:[2, 1, 4, 3, 5]

原鏈表轉換爲列表:[]
最終的鏈表轉換爲列表:[]

已知 鏈表節點的定義、鏈表與列表相互轉換 的代碼如下:

class ListNode:  # 單鏈表
    def __init__(self, val=0, next=None):
        self.val = val  # 鏈表節點上存儲的元素
        self.next = next  # 指向下一個鏈表節點


def list_to_list_node(numbers):  # 將列表轉換爲單向鏈表,並返回鏈表的頭節點
    dummy_head = ListNode(0)
    pre = dummy_head
    for number in numbers:
        pre.next = ListNode(number)
        pre = pre.next
    pre = dummy_head.next
    return pre


def list_node_to_list(node):  # 將單向鏈表轉換爲列表
    result = []
    while node:
        result.append(node.val)
        node = node.next
    return result

實現思路

  • 假設初始鏈表節點如下:節點1 -> 節點2 -> 節點3 -> 節點4 -> 節點5,設置一個虛擬頭節點後,鏈表變爲:虛擬頭節點 -> 節點1 -> 節點2 -> 節點3 -> 節點4 -> 節點5
  • 首先,需用3個變量保存在除虛擬頭節點外的前3個節點,因爲等會需要改變節點的指向
  • 第一步,讓當前節點通過 next 指向節點2
  • 第二步,讓當前節點的下個節點通過 next 指向節點1
  • 第三步,讓當前節點的下下個節點通過 next 指向節點3
  • 第四步,讓當前節點移動2位,也就是到 節點1 的位置,以便繼續交換後面的節點
  • 通過上面幾步處理後,鏈表變爲:虛擬頭節點 -> 節點2 -> 節點1 -> 節點3 -> 節點4 -> 節點5,同時當前節點已經變爲 節點1
  • 循環以上幾步操作,直到當前節點的下個節點或下下個節點出現空時,說明節點交換完成,最終得到的鏈表爲:虛擬頭節點 -> 節點2 -> 節點1 -> 節點4 -> 節點3 -> 節點5
  • 最後,將鏈表虛擬頭節點的下一個節點,也就是將 節點2 返回即可

代碼實現--迭代

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        dummy_head = ListNode(next=head)  # 設置虛擬頭節點
        cur = dummy_head
        while cur.next is not None and cur.next.next is not None:
            tmp1, tmp2, tmp3 = cur.next, cur.next.next, cur.next.next.next  # 臨時節點1、節點2、節點3
            cur.next = tmp2  # 改變節點指向,當前節點通過 next 指向節點2
            cur.next.next = tmp1  # 改變節點指向,下個節點通過 next 指向節點1
            cur.next.next.next = tmp3  # 改變節點指向,下下個節點通過 next 指向節點3
            cur = cur.next.next  # 當前節點移動2位(變爲節點1)
        return dummy_head.next

代碼實現--遞歸

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        cur = head
        while cur is None or cur.next is None:  # 遞歸終止條件:當前節點或下個節點爲空
            return cur
        post = cur.next  # 臨時保存下個節點
        cur.next = self.swapPairs(post.next)  # 改變節點指向,當前節點通過 next 指向經過遞歸處理的子鏈表
        post.next = cur  # 改變節點指向,下個節點通過 next 指向當前節點
        return post  # 每次遞歸調用後,當前節點和下個節點指向發生改變,子鏈表都是從下個節點開始

更多Python編程題,等你來挑戰:Python編程題彙總(持續更新中……)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章