リンクリストの最後のnノードを削除します

ここに画像の説明を挿入
ここに画像の説明を挿入

アイデア:

ダブルトラバーサルを使用すると問題を確実に解決できますが、問題を解決するにはトラバースする必要があるため、考え方を変える必要があります。

ダブルポインタpとqが設定されていて、qが最後のNULLを指し、pとqの間の要素数がnの場合、pの次のポインタを削除して要件を完了することが想像できます。

ここに画像の説明を挿入

#include<iostream>
#include<vector>
using namespace std;
 struct ListNode {
    
    
     int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {
    
    }
  };
 
class Solution {
    
    
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {
    
    
        ListNode* p=head;
        ListNode* q=head->next;
        int num = 0;//计算p和q之间存在几个节点
        while (q)
        {
    
    
            if (num <n)
            {
    
    
                q = q->next;
                num++;
            }
            else 
            {
    
    
                q = q->next;
                p = p->next;
            }
        }
        //删除p后面的一个顶点
        ListNode* temp = p->next;
        p->next = p->next->next;
        delete temp;
        return head;
    }
};
//测试-----------------
void input(ListNode* l)
{
    
    
    int num;
    while (1)
    {
    
    
        cin >> num;
        if (num == -1)
            return;
        ListNode* newNode = new ListNode(num);
        newNode->next = l->next;
        l->next = newNode;
    }

}
void display(ListNode* l)
{
    
    
    if (l== NULL)
    {
    
    
        return;
    }
    cout << l->val;
    display(l->next);
}
void test()
{
    
    
    ListNode* l = new ListNode(0);
    input(l);
    Solution s;
   l=s.removeNthFromEnd(l, 2);
    cout << "链表打印:" << endl;
    display(l->next);
    cout << endl;
}
int main()
{
    
    
    test();
    system("pause");
    return 0;
}

ここに画像の説明を挿入

再帰

 class Solution {
    
    
 public:
        int cur = 0;//记录从尾结点回溯的时候,是倒数第几个节点
        ListNode* removeNthFromEnd(ListNode* head, int n) {
    
    
            if (!head) return NULL;//用来判断是否递归到了最后一个节点
            //一开始通过递归找到最后一个节点,进行回溯的时候每一次判断当前是否为要删除的节点
            head->next = removeNthFromEnd(head->next, n);
            cur++;
            //找到要删除的节点,返回当前节点的下一个节点,那么接收的时候,当前节点的前一个节点的next指针就指向了当前节点的下一个节点,相当于完成了删除当前节点的操作
            if (n == cur) return head->next;
            //回溯的时候如果不是要删除的节点,那么当前节点的前一个节点就依然指向当前节点,不做删除操作
            return head;
        }
    };

おすすめ

転載: blog.csdn.net/m0_53157173/article/details/115220600