Description
Given a linked list, remove the n-th node from the end of list and return its head.
Example
Given linked list: 1->2->3->4->5, and n = 2.
Output: 1->2->3->5.
解题思路
最常见的解题思路就是循环两次
第一次得到所有的节点数量
第二次找到要删除的位置进行删除
需要注意的就是不存在p.next.next(p.next == null)的情况
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode p = head;
int count = 0;
int i;
while(p.next != null){
count ++;
p = p.next;
}
count -= n;
if(count < 0)
return head.next;
p = head;
for(i = 0; i < count; i++)
p = p.next;
p.next = p.next.next;
return head;
}
}
One Pass Solution
题目有给出:能不能在一次循环中得到答案
hmmmm没错我又是看solution的QuQ
假设现在有一个长为5的list,要删除倒数第二个数
就给他设置一个p1指针,一个p2指针,像筷子一样夹着n个节点
p1、p2一起移动,当p2指针移动到null的时候,就是p1指针要删除的地方
但是这样会有一个问题,如果要删除的是第一个数该怎么办
solution非常巧妙
它在head之前设置了一个pre-head,p1、p2都从那里开始,这样就算删除的是第一个数,也可以完美的删除
也就是说,初始状态变成了这样:
之后的步骤与之前一样,随后返回pre.next就可以得到结果了
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode header = new ListNode(0);
header.next = head;
ListNode p1 = header;
ListNode p2 = header;
int i;
for(i = 0; i < n + 1; i++){
p2 = p2.next;
}
while(p2 != null){
p1 = p1.next;
p2 = p2.next;
}
p1.next = p1.next.next;
return header.next;
}
}
其他
- 两个算法的时间是一样的hhhh都是7ms
- 应该是数据量不够大,体现不出one pass的优点