難度中等428收藏分享切換為英文接收動態反饋
給定乙個單鏈表 l:l0→l1→…→l
n-1→ln ,
將其重新排列後變為: l0→l
n→l1→l
n-1→l2→l
n-2→…
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
示例 1:
示例 2:給定鍊錶 1->2->3->4, 重新排列為 1->4->2->3.
因為鍊錶不支援下標訪問,所以我們無法隨機訪問鍊錶中任意位置的元素。給定鍊錶 1->2->3->4->5, 重新排列為 1->5->2->4->3.
因此比較容易想到的乙個方法是,我們利用線性表儲存該鍊錶,然後利用線性表可以下標訪問的特點,直接按順序訪問指定元素,重建該鍊錶即可。
複雜度分析
class solution:
def reorderlist(self, head: listnode) -> none:
if not head:
return
vec = list()
node = head
while node:
node = node.next
i, j = 0, len(vec) - 1
while i < j:
vec[i].next = vec[j]
i += 1
if i == j:
break
vec[j].next = vec[i]
j -= 1
vec[i].next = none
注意到目標鍊錶即為將原鍊錶的左半端和反轉後的右半端合併後的結果。
這樣我們的任務即可劃分為三步:
找到原鍊錶的中點(參考「876. 鍊錶的中間結點」)。
我們可以使用快慢指標來 o(n)地找到鍊錶的中間節點。
將原鍊錶的右半端反轉(參考「206. 反轉鍊錶」)。
我們可以使用迭代法實現鍊錶的反轉。
將原鍊錶的兩端合併。
因為兩鍊錶長度相差不超過 1,因此直接合併即可
複雜度分析
class solution:
def reorderlist(self, head: listnode) -> none:
if not head:
return
mid = self.middlenode(head)
l1 = head
l2 = mid.next
mid.next = none
l2 = self.reverselist(l2)
self.mergelist(l1, l2)
def middlenode(self, head: listnode) -> listnode:
slow = fast = head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
return slow
def reverselist(self, head: listnode) -> listnode:
prev = none
curr = head
while curr:
nexttemp = curr.next
curr.next = prev
prev = curr
curr = nexttemp
return prev
def mergelist(self, l1: listnode, l2: listnode):
while l1 and l2:
l1_tmp = l1.next
l2_tmp = l2.next
l1.next = l2
l1 = l1_tmp
l2.next = l1
l2 = l2_tmp
213 重排鍊錶
題目描述 給定乙個單鏈表 l l0 l1 ln 1 ln 將其重新排列後變為 l0 ln l1 ln 1 l2 ln 2 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。示例 1 給定鍊錶 1 2 3 4,重新排列為 1 4 2 3.示例 2 給定鍊錶 1 2 3 4 5,重新排列為 ...
143 重排鍊錶
143.重排鍊錶 給定乙個單鏈表 l l0 l1 l n 1 ln 將其重新排列後變為 l0 l n l1 l n 1 l2 l n 2 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。示例 1 給定鍊錶 1 2 3 4,重新排列為 1 4 2 3.示例 2 給定鍊錶 1 2 3 4 ...
143 重排鍊錶
題解 時間複雜度 o n 空間複雜度 o n definition for singly linked list.struct listnode listnode int x val x next nullptr listnode int x,listnode next val x next nex...