Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://oj.leetcode.com/problems/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.

解题思路:

首先想到的是,两个游标,除了遍历游标外,始终保留一个他前面的一个游标。每遍历一个节点,往后判断n步,然后看结果是不是空,如果是,就说明这个节点就是要删除的,不然就继续向后找。但还有一种可能,就是1->2->3,n=3,直接要删1。由于上面往后判断n步的时候只有两种可能,要么到了结尾正好为null,要么到了结尾还不是null。如果还没到结尾就null了,说明要删除的是第一个节点,那么直接返回即可。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head.next == null && n == 1){
            return null;
        }
        ListNode returnNode = head;
        ListNode headNode = head;
        ListNode tailNode = head.next;
        while(tailNode != null){
            ListNode tempNode = tailNode;
            for(int i = 0; i < n; i++){
                tempNode = tempNode.next;
                if(tempNode == null && i < n - 1){
                    return returnNode.next;
                }
            }
            if(tempNode == null){
                break;
            }
            tailNode = tailNode.next;
            headNode = headNode.next;
        }
        headNode.next = tailNode.next;
        return returnNode;
    }
}

 但原题要求one pass,上面可以勉强说是one,但每次都要往后检查n步。考虑一下,需要吗?事实上,我们只要先用一个node,开始就往后先移动n步,然后用一个节点和他同时开始,这样这个node到结尾的时候,说明前面那个节点就是要处理的了。具体些代码的时候,有些技巧,慢的那个节点始终指向要删除的节点的上一个节点,可以直接用headNode.next = headNode.next.next,便可删除下一个节点。

还有一个情况必须考虑,比如链表1-2-3-4,n=4,开始节点从1往后走4步已经空了,那么证明要删除的是第一个节点,于是直接返回第二个节点即可。由于题目里说给的n始终是有效的,就是说n始终小于等于链表的长度,所以tail为空的情况只可能已经走了n步,不可能走了一半就空了。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head.next == null && n == 1){
            return null;
        }
        ListNode returnNode = head;
        ListNode headNode = head;
        ListNode tailNode = head;
        
        for(int i = 0; i < n; i++){
            tailNode = tailNode.next;
            if(tailNode == null){
                return returnNode.next;
            }
        }
        while(tailNode.next != null){
            tailNode = tailNode.next;
            headNode = headNode.next;
        }
        headNode.next = headNode.next.next;
        return returnNode;
    }
}

这道题开始做的时候,第一个方法很快想出,倒是第二个很简单的方法没想出来,实在不该,瓶颈。

posted on 2015-02-04 20:03  NickyYe  阅读(165)  评论(0编辑  收藏  举报