【LeetCode】データ構造問題解決法(5) [分割リンクリスト]

所属コラム:データ構造の質問タイプで遊ぶ
ブロガーのホームページ: Chuyang785
コードホスティング: chuyang785
ご支援ありがとうございます。あなたの「いいね!」と注目が私にとって最大のサポートです。
ブロガーもより良いブログ記事を作成するためにさらに努力します。
ついてきて、ついてきて、ついてきて、大事なことは三回言ってください!

1. 話題のソース

リンクされたリストを分割する

2. トピックの説明

リンク リストのヘッド ノード head と特定の値 x が与えられた場合、x 未満のすべてのノードが x 以上のノードの前に表示されるようにリンク リストを分割してください。
各パーティション内のノードの初期相対位置を保持する必要はありません。
ここに画像の説明を挿入

3. 問題解決のアイデア

この質問の意味は、x 未満のデータを左側に、x 以上のデータを右側に配置するというもので、順序を変更しても元の順序は変わりません。
私たちのアイデアは、2 つのリンク リストを作成し、1 つのリンク リスト LessHead は x 未満のデータを格納し、もう 1 つのリンク リスト GreaterHead は x 以上のデータを拡大し、最後に 2 つの側を 1 つのリンク リストにマージしてから、新しいリンクリストの最初のノードのアドレス。

リンクを容易にするために、リンクされた 2 つのリストのヘッド ノードとして、val が無効なデータであるが、next が次のアドレスを指すセンチネルを作成する方法を使用します。
次に、リンク リストを横断するための変数 cur を作成し、サイズに応じてそれらを異なるリンク リストに割り当てます。

図:
ここに画像の説明を挿入
x=3 のとき、cur はトラバースを開始します。まず、最初のノードのデータは 1 であり、3 より小さいです。それを LessHead リンク リストにリンクし、LessNext を使用してリンクされたノードを記録します。 Diandian は、将来リンクするときに LessHead で表すだけで済み、リンクが完了した後にリンク先リストの先頭ノードのアドレスを返すときに、直接 LessHead に戻れるという利点があります。
ここに画像の説明を挿入
同じ cur が最初のノードを通過した後、2 番目のノードにアクセスするには cur=cur->next にするだけで済みます。これは、最初のノードをチャネルにリンクしたときに 2 番目のノードを指す最初のノードを破棄しなかったためです。ノードであっても、最初のノードを通じて 2 番目のノードを見つけることができます。同様に、greaterNext を使用して次のノードのアドレスを表します。
ここに画像の説明を挿入
類推すると、cur が NULL を指すとループが停止します。
次のステップでは、2 つのリンクされたリストをマージします。
ここに画像の説明を挿入
行にlessTail->next=greaterHead->next;を設定するだけです。
しかし、ここで特に重要なことは、接続した後、greaterNext がどこを指すのかということです。それは本当に NULL を指しているのでしょうか? 答えは否定的です。
前のリンクに戻りましょう。5
ここに画像の説明を挿入
つのデータを保存する次のリンクが 2 のアドレスを指していることがわかります。
ここに画像の説明を挿入

画像解析はこんな感じになるのですが、このままではループになってしまい、アドレスを返す際にメモリの問題が発生してしまいます。
したがって、ここでの解決策は、greaterNext->next を空にすること、つまり、greaterNext->next=NULL にすることです。

4. コード表示

struct ListNode* partition(struct ListNode* head, int x)
{
    
    
    //创建哨兵位,方便链接
    struct ListNode* lessHead,*lessTail,*greaterHead,*greaterTail;
    //存放小于x的数据
    lessHead=lessTail=(struct ListNode*)malloc(sizeof(struct ListNode));
    lessHead->next=NULL;
    
	//存放大于等于x的数据
    greaterHead=greaterTail=(struct ListNode*)malloc(sizeof(struct ListNode));
    greaterHead->next=NULL;
	
	//遍历链表指针
    struct ListNode* cur=head;

    while(cur)
    {
    
    
        //尾插
        if(cur->val < x)
        {
    
    
            lessTail->next=cur;
            lessTail=cur;
        }
        else
        {
    
    
            greaterTail->next=cur;
            greaterTail=cur;
        }
        cur=cur->next;
    }
    //链接两个链表
    lessTail->next=greaterHead->next;
    //消除环,我们的5最后还指向我们2,这个时候就形成了一个环、
    greaterTail->next=NULL;

    struct ListNode* newnode=lessHead->next;
    //最后释放两个创建的内存空间
    free(lessHead);
    free(greaterHead);
    return newnode;
}

おすすめ

転載: blog.csdn.net/qq_74276498/article/details/130486885