LeetCode OJ 292.Nim Gam19. 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.

最近特别喜欢解决链表方面的问题,感觉指针指来指去还是挺有意思的,而且在解决指针问题时有好多技巧来降低时间复杂度和空间复杂度。

上面这个题目就是一个比较典型的用双指针来解决问题的例子。按照正常的想法:一次遍历怎么可能做到定位这个指针呢?小白的想法是先计算指针的长度length吧,然后从前往后遍历(length-n)个节点,则下一个节点就是我们要删除的节点。这样最起码要遍历两遍。

如果我们有两个指针,一个快指针和一个慢指针,快指针比慢指针快(n-1)步,那么如果快指针.next==null时,慢指针正好指向那个我们要删除的指针。这样一次遍历就能完成这个问题。怎么样?这个方法是不是很巧妙呢?代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; }
 7  * }
 8  */
 9 public class Solution {
10     public ListNode removeNthFromEnd(ListNode head, int n) {
11         if(n <= 0 || head==null) return head;
12         ListNode fast = head;       //快指针
13         ListNode slow = head;       //慢指针
14         ListNode pre = null;
15         
16         while(fast.next != null){
17             if(n <= 1){             //快指针比慢指针快n-1步
18                 pre = slow;
19                 slow = slow.next;
20             }
21             fast = fast.next;
22             n--;
23         }
24         if(slow == head) head = head.next;//如果删除的是头指针
25         else pre.next = slow.next;        //删除的不是头指针
26         return head;
27     }
28 }
原文地址:https://www.cnblogs.com/liujinhong/p/5386453.html