LeetCode 19. Remove Nth Node From End of List

19. Remove Nth Node From End of List

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.

题目描述:
给出一个数组链表的头指针,和一个数字n,去掉链表中倒数第n个元素,并且返回新的链表的指针。

解题思路:
题目中告诉我们尽量用一次的pass的就能完成题目的要求,那到底我们怎么才能知道当前的元素是第几个元素。如果找到了倒数第n个元素的位置,那么剩下的工作就是简单地去掉这个位置的元素了。
因此,我用了一个queue来保存列表的元素,从头开始遍历这个数组链表,依次往queue里面push链表的节点。如果queue的size已经到达n+1,那么每push一个节点,就要pop一个节点,以使得queue里面的最大元素个数不超过n+1
当遍历完整个链表之后,这时候会有2种情况:

  1. queue的top就是原来链表的头指针,也就是说n的大小就是整个链表元素的个数,此时的queue元素个数就是n,我们应该去除倒数第n个元素,就是del掉第1个元素,然后要返回queue的第二个元素;

  2. queue的元素个数为n+1,此时queue的top就是要去除的元素的前一个元素,queue的第二个元素就是要去除的元素,那么此时需要将queue的top节点的next指向第queue的第三个元素,同时把第二个元素del掉。

代码:

#include <iostream>
#include <queue>

using namespace std;

/**
 * Definition for singly-linked list.
 */
 struct ListNode {
     int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
 };

void PrintList(ListNode* l) {
    if (l == NULL) {
        return;
    }
    ListNode* currentNode = l;
    while (currentNode != NULL) {
        if (currentNode != l) {
            cout << "->" ;
        }
        cout << currentNode->val;
        currentNode = currentNode->next;
    }
    cout << endl;
}

ListNode* Convert2ListNode(string val) {
    if (val == "") {
        return NULL;
    }
    ListNode* l = new ListNode(val[0] - '0');
    ListNode* start = l;
    std::string::iterator it = val.begin() + 1;
    for(; it != val.end(); it++) {
        l->next = new ListNode(*it - '0');
        l = l->next;
    }
    return start;
}


class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        queue<ListNode*> q;
        ListNode* temp = head;
        while(temp != NULL) {
            q.push(temp);
            if (q.size() > n + 1) {
                q.pop();
            }
            temp = temp->next;
        }
        if(q.size() < n + 1) {
            q.pop();
            if (q.size() > 0) {
                return q.front();
            }
            else {
                return NULL;
            }
        }
        else {
            ListNode* pre = q.front();
            q.pop();
            ListNode* middle = q.front();
            q.pop();
            pre->next = middle->next;
            delete middle;
            return head;
        }
    }
};

int main(int argc, const char * argv[]) {
    Solution sln;
    ListNode* l = Convert2ListNode("1");
    //PrintList(l);
    PrintList(sln.removeNthFromEnd(l, 1));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值