思路:
1.首先当只有一个节点时,n=1 ,那删除后就是空节点
2.还有当n的值刚好是头节点,例如倒数第3个节点,而节点长度为3,这种就是返回head.next了
3.其他情况,我们将slow指向到 要删除节点的前一个节点,那怎么才能指到呢?我们用fast节点先指向头节点,然后偏移 n - 1 个节点位置,此时[slow,fast]长度为n,如果fast节点后是空节点,那么就是第2中情况了,否则fast = fast.next,然后[slow,fast]长度为n+1,循环遍历,知道fast节点的next为空,然后slow.next = slow.next.next就删除了


/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param n int整型 
     * @return ListNode类
     */
    public ListNode removeNthFromEnd (ListNode head, int n) {
        // write code here
        if(head == null){
            return null;
        }
        if(n == 1 && head.next == null){
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        while(n - 1 >  0){
            n --;
            fast = fast.next;
            if(fast == null){
                return head;
            }
        }
        if(fast.next == null){
            return head.next;
        }
        fast = fast.next;
        while(fast.next != null){
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next;

        return head;
    }
}