58. Sort List
11133 ワード
道しるべ 接続リストをO(nlogn)で に並べ替える
これは、接続リストを入力値として使用するため、直接ソートを実現する必要がある良い問題です. しかし,時間的複雑さはO(nlogn)で解決しなければならないという制約もある.
接続リスト入力についてはPythonでソートできる個別の関数はないため,直接ソートアルゴリズムを実現する必要がある.
入力値-1->5->3->4->0接続リストの集計ソート手順を以下に示します.
ソートされた分割征服を統合するためには,中央を分割する必要がある. 図にも5を基準とした分割過程が現れている.
ただし,接続リストは全長が分からないため,ここではrunnerテクニックを用いた.
これにより、
最後に
分割後に再帰呼び出しを行います.
図3は
この値を基準として再帰呼び出しを続けると、最終接続リストは-1、5、3、4、0の単一項目に分割されます.
最後に、最終的に分割されたアイテムを再結合して返します.
単純なマージではなくサイズを比較することでソートします.
ここで、
まず すなわち
前の2つのソートリストのマージ問題は必ずしも
<集計ソートを実施する最後の比較フェーズ>
当初、
その後は交換せず、
最後に、4の
再呼び出しされた部分に遡ると,−1>0−>3−>4−>5と決定され,最終的なソートは良好に行われた.
この問題を仮想パーティションなどの従来の高速ソートアルゴリズムで実現すると、タイムアウトが発生し、解決できません. の高速ソートをさらに最適化してこそ、解を求めることができる.
Pythonでは、タイムアウトして解析できませんがjavaとC++は解析できますが、マージソートよりも時間がかかります.
1、2、3段の3項目からなる1000個の入力値のテスト例があり、この部分ではPythonのクイックソートがタイムアウトし続けている.
高速ソートは典型的な不安定なソートであり、同じ値を繰り返しても交換を試み続けます.
接続リストは、プロパティ上の任意のピボットを指定することが困難なため、ここでは常にピボットを最初の値に設定します.この場合、ソートされたリストが入力値として使用されると、バランスのとれたリストに分割され続け、最悪の結果が表示されます.
これも、高速ソートが入力値によってパフォーマンスのばらつきが大きく、処理が困難なため、パフォーマンスが良くても実際の作業ではあまり使用されない理由です.
この問題はソートアルゴリズムを直接実現する必要はない.
多くのプログラミング言語が標準ライブラリでパフォーマンスの良いソートアルゴリズムを提供しているためです.
実行時間をさらに短縮する必要がある符号化テストでは,これが最も賢明な方法であり,実際の作業では当然この方法も用いられる.
ホワイトボードにアルゴリズムを記述する必要がある場合は、避けるべきです.
君は代弁したほうがいい.
インプリメンテーションコード
接続リストをPythonのリストとして作成します.
Pythonの組み込みソート関数
並べ替えられたリストを接続リストとして再リストします.
ここで
ポインタ変数は、接続リストを巡回するために
次に、ルートノード
この解答は84 ms以内に完成することができ、最も簡単で、直観的で、容易である. の他の制限事項がなければ、賢明に利用する必要がある.
1.集計ソート(320ミリ秒)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
#두 리스트 병합
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 and l2:
if l1.val > l2.val:
l1, l2 = l2, l1
l1.next = self.mergeTwoLists(l1.next, l2)
return l1 or l2
def sortList(self, head: ListNode) -> ListNode:
if not(head and head.next):
return head
#런너 기법 활용
half, slow, fast = None, head, head
while fast and fast.next:
half, slow, fast = slow, slow.next, fast.next.next
half.next = None
#분할 재귀 호출
l1 = self.sortList(head)
l2 = self.sortList(slow)
return self.mergeTwoLists(l1, l2)
これは、接続リストを入力値として使用するため、直接ソートを実現する必要がある良い問題です.
接続リスト入力についてはPythonでソートできる個別の関数はないため,直接ソートアルゴリズムを実現する必要がある.
入力値-1->5->3->4->0接続リストの集計ソート手順を以下に示します.
ソートされた分割征服を統合するためには,中央を分割する必要がある.
ただし,接続リストは全長が分からないため,ここではrunnerテクニックを用いた.
half, slow, fast
3変数を作成し、slow
を1つ前進させ、fast
を2つ前進させます.これにより、
fast
が先端に到達すると、slow
は中央に到達する.half
はslow
の正遷移値である.最後に
half.next = None
であり、half
の位置を基準として接続リスト関係を切断する.分割後に再帰呼び出しを行います.
head
は開始ノードであり、slow
は探索によって発見された中心点である.図3は
slow
である.この値を基準として再帰呼び出しを続けると、最終接続リストは-1、5、3、4、0の単一項目に分割されます.
最後に、最終的に分割されたアイテムを再結合して返します.
単純なマージではなくサイズを比較することでソートします.
mergeTwoLists()
メソッドは、長さにかかわらず、l1
を移動するポインタを再帰的に呼び出し、ソートを返す接続リストを入力値として受け入れる.ここで、
return l1 or l2
の値がl1
であれば、常にl1
を返し、l1
の値がNone
であればl2
を返します.まず
l1
である.前の2つのソートリストのマージ問題は必ずしも
l1 or l2
を比較する必要はありません.l1
がNone
であれば、事前に交換する方法であり、どのように解いても結果は同じです.当初、
l1
のうち−1、l2
のうちの0は入力値であり、l1
のうちのnext
のうちの5は0より大きいので、交換が行われる.その後は交換せず、
next
の順で3,4に接続し続けた.最後に、4の
next
はNone
であり、この場合、return l1 or l2
の部分はl2
の値、すなわち5を返す.再呼び出しされた部分に遡ると,−1>0−>3−>4−>5と決定され,最終的なソートは良好に行われた.
2.クイックソート(タイムアウト)
この問題を仮想パーティションなどの従来の高速ソートアルゴリズムで実現すると、タイムアウトが発生し、解決できません.
Pythonでは、タイムアウトして解析できませんがjavaとC++は解析できますが、マージソートよりも時間がかかります.
1、2、3段の3項目からなる1000個の入力値のテスト例があり、この部分ではPythonのクイックソートがタイムアウトし続けている.
高速ソートは典型的な不安定なソートであり、同じ値を繰り返しても交換を試み続けます.
接続リストは、プロパティ上の任意のピボットを指定することが困難なため、ここでは常にピボットを最初の値に設定します.この場合、ソートされたリストが入力値として使用されると、バランスのとれたリストに分割され続け、最悪の結果が表示されます.
これも、高速ソートが入力値によってパフォーマンスのばらつきが大きく、処理が困難なため、パフォーマンスが良くても実際の作業ではあまり使用されない理由です.
3.組み込み関数を使用するための実用的な方法(84 ms)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def sortList(self, head: ListNode) -> ListNode:
#연결 리스트 -> 파이썬 리스트
p = head
lst: List = []
while p:
lst.append(p.val)
p = p.next
#정렬
lst.sort()
#파이썬 리스트 -> 연결 리스트
p = head
for i in range(len(lst)):
p.val = lst[i]
p = p.next
return head
この問題はソートアルゴリズムを直接実現する必要はない.
多くのプログラミング言語が標準ライブラリでパフォーマンスの良いソートアルゴリズムを提供しているためです.
実行時間をさらに短縮する必要がある符号化テストでは,これが最も賢明な方法であり,実際の作業では当然この方法も用いられる.
ホワイトボードにアルゴリズムを記述する必要がある場合は、避けるべきです.
君は代弁したほうがいい.
インプリメンテーションコード
接続リストをPythonのリストとして作成します.
Pythonの組み込みソート関数
sort()
について、次の操作を行います.並べ替えられたリストを接続リストとして再リストします.
ここで
p
はポインタです.ポインタ変数は、接続リストを巡回するために
p
に設定され、巡回およびチャージの役割を果たす.次に、ルートノード
head
に戻る.この解答は84 ms以内に完成することができ、最も簡単で、直観的で、容易である.
Reference
この問題について(58. Sort List), 我々は、より多くの情報をここで見つけました https://velog.io/@corone_hi/58.-Sort-Listテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol