19.ノードのリストを削除するには、相互のリストの最後に[M]からn番目のノードを削除N

タイトル

リンクされたリストが与えられると、削除n個のリストの最後から番目のノードを、その頭を返します。
*例:
与えられたリンクリスト:1-> 2-> 3-> 4-> 5、及びN = 2の
端部から第2のノードを除去した後は、リンクされたリストとなる1-> 2-> 3-> 5。
注:
与えられたnは常に有効になります。
フォローアップ:**
あなたは1回のパスでこれを行うことができますか?


考え

思考:2パス

第二ノードauxListを定義し、それは境界条件の決意を簡素化するために、リストの先頭に次のノードを指し、例えば、唯一のヘッドノードを削除し、リストをノード。二次ノードauxListへのポインタを設定し、ノードから始まる、指定されるまで、2番目のパス(2つのパス);リストの長さLを得るための最初のパス(ワンパス)、nは停止され、今回が最初に到達するのLn(\を\)ノード、第\(LN \)と第二\(LN + 2 \)ノードは、削除セクション再接続する\(\のLn + 1)ヒトによるノード(一つのノードが増加します)。

2考える:ワンパス

私たちは、サイクルを通じて、N個のノードのリストの逆数削除を達成するためにどのように、トピックを考えてみましょう。

  • ダブルポインタ方式は、
    カウントダウンの問題を解決するために両手法を使用することができます。
    • 最初のポインタは、制御サイクルタイムのために高速であります
    • 横断するため、ゆっくりと第2のポインタ、
      二つのポインタは、二つの異なるリストに対応する、すなわち二つのポインタ、リンクリストを指しています。介して第1の時間を達成するには、\(LN \)は、ノード、まず最初にポインタ「実行」終了n回で、その後、第2のスタートポインタ「実行」、およびnは最初のポインタを削除します最初のノードが行ったL-1のノードは、この時点でのサイクル数は、第二ランリストに対応している\(LN \)リンクされたリストは、最後から二番目の数nを見つけるためにするように、数。
  • 再帰的な
    挿入および欠失は、1つのノード上での操作に関与しなければならないので、挿入や削除の単一のリストを含み、再帰的に考えることができます。削除を開始するN + 1層に戻ったときに、最後のノードが第1階層に設定され、層fによって層が、返されます。

ヒント

単一のリスト

![](https://i.loli.net/2019/05/20/5ce25ec0d432a91619.jpg)
単一リンクリストの模式図は、ヘッダが空である、後続ノードヘッダが「1」であります

リストを検索する
最初のキーワードリストL kを見つけることは元素であり、その要素へのポインタへのポインタを返します。リストは、(NIL)空のk個のキーワードを返し、オブジェクトされない場合

//List-Search(L,k)
x = L.head;
while x != NIL and x.key != k    //NIL为空
  x = x.next
return x

リストを挿入

![](https://i.loli.net/2019/05/20/5ce2611b14b8675624.jpg)
図:リストを挿入

リストを削除


図:リストを削除します

---

C ++

  • 思考
ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* auxList = new ListNode(0);
        auxList->next = head;
        int length = 0;
        ListNode* pass = head;
        while(pass != NULL){
            length ++;
            pass = pass->next;
        }
        
        length -= n;
        pass = auxList;
        while(length > 0){
            length --;
             pass = pass->next;
        }
        
         pass->next = pass->next->next;
        
        return auxList->next; //这里返回next是因为auxList的next才是原来的链表
    }
  • 二つの考え方(1)
ListNode* removeNthFromEnd(ListNode* head, int n) {
       ListNode* auxList = new ListNode(0);
        auxList->next = head;
        ListNode* point1 = auxList;
        ListNode* point2 = auxList;
        
        for(int i = 1; i <= n + 1;i++)
            point1 = point1->next;
        
        while(point1 != NULL){
            point1 = point1->next;
            point2 = point2->next;
        }
        
        point2->next = point2->next->next;
        
        return auxList->next;
    }
  • 考える2(2)
ListNode* removeNthFromEnd(ListNode* head, int n) {
       ListNode* auxList = new ListNode(0);
        auxList->next = head;
        remove(auxList, n);
        return auxList->next;
    }
    
    int remove(ListNode* head, int n){
        if(head->next == NULL)
            return 1;
        int levels = remove(head->next, n) + 1; 
        if(levels == n+1)
            head->next = head->next->next;
        return levels;
    }

パイソン


参照

[1]はじめにアルゴリズム10章10.2、P131
[2] http://www.cnblogs.com/skywang12345/p/3561803.html

おすすめ

転載: www.cnblogs.com/Jessey-Ge/p/10993506.html