Given a linked list, remove the nth nodefrom 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 becomes1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
既然给了note,那我们得关注一下,首先,所给的n都是合法的,其次,只允许扫描一遍。
扫描一遍,还要能逆序定位链表的节点,看来我们需要借助关联容器了。
思路:扫描链表的节点,我们以zero-based的下标来作为关联容器的键,链表全部进关联容器之后,我们就可以按下标取节点了,管他顺序逆序。
Leetcode的Accepted Solutions Runtime Distribution(2015-06-05)
源码:(VS2013)如果需要提交leetcode只需要把函数中的代码复制过去即可。
#include <iostream>
#include <map>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeNthFromEnd(ListNode* head, int n);
int main()
{
ListNode l1(1);
ListNode* pl1 = &l1;
ListNode l2(2);
ListNode* pl2 = &l2;
ListNode l3(3);
ListNode* pl3 = &l3;
ListNode l4(4);
ListNode* pl4 = &l4;
ListNode l5(5);
ListNode* pl5 = &l5;
pl1->next = pl2;
pl2->next = pl3;
pl3->next = pl4;
pl4->next = pl5;
//cout << removeNthFromEnd(pl1, 2)->val;
return 0;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
//链表如果只有一个节点,那么已知(Given n will always be valid.)条件下
//返回的必然是空指针
if (!head->next) return NULL;
//扫描一次,把链表节点存进map中
map<int, ListNode*> myMap;
int index = 0;
while (head)
{
myMap.insert(pair <int, ListNode*>(index, head));
index++;
head = head->next;
}
//注意,我们存进map中的链表zero-based的,此时的index刚好表示链表长度。
//因此,(index--)才是表示链表最后一个节点的下标(zero-based)。
index--;
//那么find(index - (n - 1))就表示倒数第n个节点啦,
//倒数第1个的话,代入n=1;,表达式变成find(index)。
//倒数第2个的话,代入n=2;,表达式变成find(index-1)。
//删除倒数第一个,只要把倒数第二个的next赋空
if (1 == n) (--myMap.find((index - (n - 1))))->second->next = NULL;
//删除倒数最后一个,即顺数第一个,也简单。
else if (n == index + 1)
{
myMap.find(0)->second->next = NULL;//这句注释掉也能过leetcode(2015-06-05),钻牛角尖的感觉
return myMap.find(1)->second;
}
//删除中间的节点,把被删除节点的前驱节点的next赋为被删除节点的后驱节点即可。
else (myMap.find((index - (n - 1) - 1)))->second->next = (myMap.find((index - (n - 1) + 1)))->second;
return myMap.find(0)->second;
}