leetcode 鍊錶的排序問題

2021-10-04 19:22:28 字數 4036 閱讀 9310

題目描述:在 o(n log n) 時間複雜度和常數級空間複雜度下,對鍊錶進行排序。例如:輸入: 4->2->1->3

輸出: 1->2->3->4。

思路分析:因為要求在o(nlogn)的時間複雜度,所以想到使用歸併排序。下面對歸併排序做個介紹。

歸併排序

基本方法如下:

(1)把待排序序列的n個記錄看成n個有序子串行,每個子串行長度為1.

(2)把當時序列組裡的有序子串行兩兩歸併,完成一遍後序列組裡的排序序列個數減半,每個子串行長度加倍。

(3)對加長有序子串行重複(2)操作,最終得到乙個n的有序序列。

def

merge

(list_left, list_right)

:"""

入引數組都是有序的,此處將兩個有序陣列合併成乙個大的有序陣列

"""# 兩個陣列的起始下標

l, r =0,

0 new_list =

while l <

len(list_left)

and r <

len(list_right)

:if list_left[l]

< list_right[r]:)

l +=

1else:)

r +=

1 new_list += list_left[l:

] new_list += list_right[r:

]return new_list

defmerge_sort

(mylist)

:"""歸併排序

mylist: 待排序陣列

return: 新陣列list

"""iflen

(mylist)

<=1:

return mylist

mid =

len(mylist)//2

list_left = merge_sort(mylist[

:mid]

) list_right = merge_sort(mylist[mid:])

return merge(list_left, list_right)

對應這題,由於是鍊錶,我們無法直接得到鍊錶的中點,這可以通過快慢指標得到,在合併兩個有序鍊錶時需要建立乙個臨時指標,注意與陣列合併的不同,可以自己在紙上嘗試一下節點是如何轉換的。

# definition for singly-linked list.

class

listnode

:def

__init__

(self, x)

: self.val = x

self.

next

=none

class

solution

:def

sortlist

(self, head: listnode)

-> listnode:

ifnot head or

not head.

next

:return head

mid = self.getmid(head)

rhead, mid.

next

= mid.

next

,none

return self.mergesort(self.sortlist(head)

,self.sortlist(rhead)

)def

getmid

(self,head):if

not head:

return head

slow = fast = head

while fast.

next

and fast.

next

.next

: slow, fast = slow.

next

, fast.

next

.next

return slow

defmergesort

(self,lhead,rhead)

: dummy = cur = listnode(0)

#使用了額外的空間,因此時間複雜度不是常數級。

while lhead and rhead:

if lhead.val<=rhead.val:

cur.

next

, lhead = lhead,lhead.

next

else

: cur.

next

, rhead = rhead,rhead.

next

cur = cur.

next

cur.

next

= lhead or rhead

return dummy.

next

迭代的歸併排序

class

listnode

:def

__init__

(self, x)

: self.val = x

self.

next

=none

class

solution

:def

sortlist

(self, head: listnode)

-> listnode:

h, length, intv = head,0,

1while h: h, length = h.

next

, length +

1 res = listnode(0)

res.

next

= head

# merge the list in different intv.

while intv < length:

pre, h = res, res.

next

while h:

# get the two merge head `h1`, `h2`

h1, i = h, intv

while i and h: h, i = h.

next

, i -

1if i:

break

# no need to merge because the `h2` is none.

h2, i = h, intv

while i and h: h, i = h.

next

, i -

1 c1, c2 = intv, intv - i # the `c2`: length of `h2` can be small than the `intv`.

# merge the `h1` and `h2`.

while c1 and c2:

if h1.val < h2.val: pre.

next

, h1, c1 = h1, h1.

next

, c1 -

1else

: pre.

next

, h2, c2 = h2, h2.

next

, c2 -

1 pre = pre.

next

pre.

next

= h1 if c1 else h2

while c1 >

0or c2 >

0: pre, c1, c2 = pre.

next

, c1 -

1, c2 -

1 pre.

next

= h intv *=

2return res.

next

leetcode 鍊錶排序

對鍊錶排序,用歸併排序。題目要求空間時間複雜度為o nlogn 但是空間複雜度為o 1 1.自己寫的程式,時間複雜度為o nlogn 但是空間複雜度為o n 用快慢指標 分別走2步和1步 找到中間節點。但是最後排序的部分,用複製將排好序的部分貼上會原來鍊錶中,這個方法比較笨,而且增加空間複雜度,並不...

leetcode 鍊錶 排序

思路 使用歸併排序。拆分 合併均採用遞迴方式。public listnode sortlist listnode head pre.next null return merge sortlist head sortlist slow public listnode merge listnode l1...

leetcode 排序鍊錶

利用歸併排序的思想,不過這裡排序的不是列表,是乙個鍊錶。具體 如下 definition for singly linked list.class listnode object def init self,x self.val x self.next none class solution obj...