leetcode刷题日记: 19.删除链表的倒数第k个节点

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

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

思路:这道题很容易就想到先扫一边链表,得到链表元素总个数,然后再次遍历链表同时计数,当计数器i从1开始直到i < size - n + 1时就可以执行删除操作。

不过这道题可以使用快慢指针的方法,从而在一次遍历的情况下就能删除倒数第n个节点。

其实思想很容易理解:

             可以把链表按照n划分为两部分,一部分从size - n + 1到size, 一部分从1 到 size - n,其中size表示链表长度,这样子如果能在一次遍历中一个指针走size - n步,则比它前n - 1的指针走的步数也必然是size - n,则这个指针到达的位置就是倒数第n个节点的前一个结点。

             图示如下:

          这里有个小技巧,添加一个哑结点(dummy node),这样子在只有一个节点的情况下就可以统一处理。

          代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        ListNode first = head;
        ListNode second = dummy;
        for(int i = 0;i < n;i++){
            first = first.next;
        }
        while(first != null){
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        ListNode res = dummy.next;
        return res;
    }
}

 

posted @ 2020-10-29 00:10  龙刃已准备出鞘  阅读(286)  评论(0编辑  收藏  举报