題目
給定一個鏈表,請在不修改節點內部值的情況下,兩兩交換其中相鄰的節點,並返回交換後鏈表的頭節點。
例如:
原鏈表轉換爲列表:[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編程題彙總(持續更新中……)