LeetCode--Remove Nth Node From End of List

本文介绍了一种在一遍扫描内从链表中删除倒数第N个节点的方法,并提供了一段C++实现代码。通过使用额外的数组来存储链表中的节点指针,可以在O(1)时间内找到待删除的节点并调整链表结构。

Question:

Given a linked list, remove the nth node from the end of list and return its head.

For example,

  • Given linked list: 1->2->3->4->5, and n = 2.

  • After removing the second node from the end, the linked list becomes 1->2->3->5.

Note:

Given n will always be valid.

Try to do this in one pass.

解题思路

尽量用一遍扫描解决问题,我就想在扫描过程中,每个节点都用一个新的指针指向,然后保存到一个数组中,数组就可以用O(1)的时间定位,也只是扫描了一遍。

数组中指针的个数就是节点的个数,然后根据删除的节点的位置,移动相应的指针即可。

实现代码

#include <iostream>
#include <vector>

using namespace std;


//Definition for singly-linked list.
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;
        if (p == NULL)
            return head;
        else
            vec.push_back(p);
        while(p->next != NULL) {
            p = p->next;
            ListNode* new_ptr = p;
            vec.push_back(new_ptr);
        }
        int cur = vec.size() - n;
        if (cur - 1 >= 0) {
            if (cur + 1 <= vec.size() - 1) {
                vec[cur - 1 ]->next = vec[cur + 1];
                } else {
                vec[cur - 1]->next = NULL;
            }
        } else {
            if (cur + 1 <= vec.size() - 1) {
                head = vec[cur + 1];
            } else
                head  = NULL;
        }
        return head;
    }
private:
    vector<ListNode*> vec;
};


int main() {
    Solution* solution = new Solution();
    ListNode* node1 = new ListNode(1);
    ListNode* node2 = new ListNode(2);
    ListNode* node3 = new ListNode(3);
    ListNode* node4 = new ListNode(4);
    ListNode* node5 = new ListNode(5);

    node1->next = node2;
    node2->next = node3;
    node3->next = node4;
    node4->next = node5;

    ListNode* head = solution->removeNthFromEnd(node1, 2);
    while(head != NULL) {
        cout << head->val << endl;
        head = head->next;
    }

    return 0;
}

转载于:https://www.cnblogs.com/zhonghuasong/p/6436183.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值