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; } }