【LeetCode】単一リンクリスト——ブラシ質問

あなたの眼窩が燃えるような瞬間は、人生の数少ない不器用で貴重な瞬間の 1 つです。

記事ディレクトリ

1. 逆単一リンクリスト

トピックのアイデアと図 

コード内で注意が必要な問題

2. リンクされたリスト要素を削除します

トピックのアイデアと図

コード内で注意が必要な問題


  皆さんこんにちは、ジニンです。

  この記事では、古典的な単一リンク リストの leetcode ペン テストの問題に対するいくつかの解決策を紹介します。

  予備知識:データ構造 - 単一リンク リスト

1. 逆単一リンクリスト

  単一リンク リストのヘッド ノードを指定して head 、リンク リストを反転し、反転したリンク リストを返してください。 

トピックのアイデアと図 

   アイデア:単一リンク リストの各ノードのポインタ フィールドの方向を前から後ろに 1 つずつ変更します。これは、単一リンク リスト全体を逆にすることです

  3 つの構造体変数 n1、n2、n3 を定義します。n1、n2 はノードのポイントを変更するために使用され、n3 は現在のノードの次のノード、つまり現在のノードの次のノードのアドレスを格納するために使用されます。  

  ポインティング ダイアグラムを変更します。最初は、n1 は何も指さず、n2 は最初のノードを指し、n3 は 2 番目のノードを指します。

​
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* n1, * n2, * n3;
    n1 = NULL;
    n2 = head;
    if(n2!=NULL)
         n3 = n2->next;
    while (n2!= NULL)
    {
        n2->next = n1;
        n1 = n2;
        n2 = n3;
        if(n3!=NULL)
            n3 = n3->next;
    }
    return n1;
}

コード内で注意が必要な問題

1. 入力ノードが空の場合、n2 には次のノードがないため、n3 = n2 -> next を設定できません。

2. 最初に方向を変更し、次に n1、n2、n3 を前方に移動します。反転後は開始ノードが終了ノードになるため、終了ノードの次のノードは NULL を指している必要があります。

3. n1、n2、n3 が進む場合、n3 が NULL かどうかを判定する必要があります。n2 が NULL になった時点で判定サイクルが終了するため、その前に n3 が先に NULL になり、判定を行います。n3 がすでに NUL の場合は、n3 を進めることはできません。それ以外の場合は、n3 が NULL になります。限界外の状況。

2. リンクされたリスト要素を削除します

  リンク リストのヘッド ノード head と整数 を指定した場合は、 リンク リスト内の val 条件を満たすノードをすべて削除し 、新しいヘッド ノードを返してください。Node.val == val 

トピックのアイデアと図

アイデア: ノードを削除するには、前のノードと次のノードの情報を知りたい場合、2 つの構造体ポインター変数を定義する必要があります。1 つは現在のノードを指し、もう 1 つは前のノードを指します。

  前のノードを指すポインタ変数 prev を定義し、最初に NULL を指すようにします; 現在のノードを指すポインタ変数 cur を定義し、最初にヘッド ノードを指すようにします

  通常の状況 (削除するノードが中間または最後にある場合) では、cur->val の値が val に等しい場合に cur に cur の次のノードをポイントさせてから、そのノードを解放するだけで済みます。元のスペース。prev の後に常に cur が続くことを確認するだけで済みます。

   最初のノードを削除する場合は、ヘッド ノードを移動する必要があります。val に等しくない最初のノードが見つかったら、cur の値を prev に割り当てます。すると、初めて prev が動き始め、次に cur が前に進みます。

struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode*cur=head;
    struct ListNode*prev=NULL;
    while(cur!=NULL)
    {
        if(cur->val==val)
        {
             if(head->val==val)
             {
                 head=cur->next;
                 free(cur);
                 cur=head;
             }
             else
             {
                prev->next=cur->next;
                free(cur);
                cur=prev->next;
             }
        }
        else
        {
            prev=cur;
            cur=cur->next;
        }
    }
    return head;
}

コード内で注意が必要な問題

  ノードを削除する必要がある場合、削除するノードの次のノードに前のノードの次のノードを割り当て、このノードのスペースを解放すると、前と削除するノードが実現されます。 。

  特定のノードを削除する必要がなく、リンク リストを通常どおり走査する場合は、毎回 prev の値を cur に割り当て、次に cur を次のノードにポイントします ( cur = cur -> next )。これにより、 prev と cur は次のようになります。同時に達成され、prev は常に cur の前のノードにあります。

おすすめ

転載: blog.csdn.net/zyb___/article/details/132011889