lc_dbp_19_removeNthFromEnd

 

/*
题目:删除链表的倒数第N个节点 middle

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:
给定的 n 保证是有效的。

进阶:
你能尝试使用一趟扫描实现吗?

 

思路:
    一次遍历:双指针。
    需找到倒数n个节点的前一个节点target。
    当快指针到尾部,慢指针应该在target
    所以快指针比慢指针多走n个距离。然后保持间距就可以了

    用哑节点dummy简化极端情况,如删除头结点的情况


*/

 



public class lc_dbp_19_removeNthFromEnd {


    public ListNode removeNthFromEnd(ListNode head, int n) {

        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode first = dummy;
        ListNode second = dummy;
        for (int i = 0; i < n; i++) {
            first = first.next;
        }
        while (first.next != null) {
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        return dummy.next;


    }

    /*
    常规做法,求链表长度,再找倒数n节点的头一个节点。但两次遍历
     */
    public ListNode removeNthFromEnd2(ListNode head, int n) {
//        用dum简化极端情况,如删除头结点的情况
        ListNode dum = new ListNode(0);//dum为head前一个
        dum.next = head;
        ListNode cur = head;
        int count = 0;
//        计数
        while (cur != null) {
            count++;
            cur = cur.next;
        }
//        重新指向dum节点,倒数第n个节点就是正数第count+1-n个节点,找到前一个节点就可以删除
        cur = dum;
        for (int i = 0; i < count - n; i++) {
            cur = cur.next;
        }
        cur.next = cur.next.next;
//        返回dum的下一个,如果只有一个节点,头节点又被删了,就返回null
        return dum.next;
    }

    class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

}

 

你可能感兴趣的:(doublePointer,LeetCode)