您的位置:首页 > Web前端 > Node.js

Leetcode 19.Remove Nth Node From End of List

2017-01-26 05:28 393 查看
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.

思路:

1. 先看简单粗暴的方法,需要two pass:第一次找到list长度m,然后m-n就是从前往后的list的位置,然后第二次遍历!

2. 题目要求one pass: 可以用recursive的方法。先recursive到最后一个元素,然后计数器加一返回,当返回遇到计数器的值等于n,则删除这个值。

3. 关于list的题,总是要考虑要求的操作是否可能会改变头节点,比如删除或增加新的头节点!就要加dummy

4. 上面的方法还是不好,太慢了!!参考了以前做的,有个技巧在里面!!用两个指针:第一个先移动n次,然后第二个再开始移动,此时第一个也在继续移动,当第一个指针移动到末尾,第二个指针的位置就是倒数第n个位置。删除即可!!

5. 在linked list中经常用到一些技巧来操作,这里就是用先后启动的两个指针来解题!

//方法1:用recursive,还是两次pass。One pass看方法2
class Solution {
public:

void helper(ListNode* head, int n,int&i){
if(head==NULL){i=0;return;}
helper(head->next,n,i);
i++;
if(i==n+1) head->next=head->next->next;
}

ListNode* removeNthFromEnd(ListNode* head, int n) {
//
ListNode* dummy=new ListNode(0);
dummy->next=head;
//head=dummy;
int pos=0;
helper(dummy,n,pos);
return dummy->next;
}
};

//方法2:two pointer:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//用dummy node来防止头节点发生变化!
ListNode* dummy=new ListNode(0);
dummy->next=head;
head=dummy;
ListNode* fast=dummy,*slow=dummy;
while(n--){
fast=fast->next;
}
while(fast->next){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
head=dummy->next;
delete dummy;
return head;
}
};


需要说明的是:指向指针的指针如下图:



上图,指向指针的指针,本质就是指向每个node的指针部分而不是指向数据部分,所以如果要删除头节点,那么可以直接改变指向指针的指针的内容,让这个指针指向头节点的下一个节点。

这里,涉及pointer-to-pointer的两个常用操作:1.移动指向指针的指针,如图就是指针指向不同的node的指针域,这个可以用方法3中的语句slow=&((*slow)->next)来实现,即:(*slow)->next是一个节点的next域,然后用&取地址;2. 修改指针所指的next域的值: *slow=(*slow)->next;

//方法3:two pointer:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//用指向指针的指针来避免头指针发生变化
//不容易理解,但代码简洁
ListNode** slow=&head, *fast=head;
for(int i=1;i<n;i++)
fast=fast->next;
while(fast->next){
fast=fast->next;
slow=&(*slow)->next;//每次改变指向指针的指针
}
*slow=(*slow)->next;//跳过一个元素
return head;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: