19. 删除链表的倒数第N个结点 - LeetCode

19. 删除链表的倒数第N个结点

题目链接

存储索引

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        List<ListNode> list = new ArrayList<>();
        ListNode p = head;
        while(p != null){
            list.add(p);
            p = p.next;
        }
        int sz = list.size();
        if(sz - n == 0) return head.next;
        if(n == 1) list.get(sz - n - 1).next = null;
        else list.get(sz - n - 1).next = list.get(sz - n + 1);
        return head;
    }
}
  • 要在一趟扫描的时间内找到倒数第N个结点,最直接的办法就是存储每个结点的索引,扫描结束后,直接删除倒数第N个即可
  • 同时要注意判断,删除的结点时第一个和最后一个的特殊情况

快慢指针

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;
        return dummy.next;
    }
}
  • 让第一个指针比第二个指针快n个,这样就只需要常数级的额外空间,就能找到倒数第N个结点,也省去了维护ArrayList的开销
  • 这里在head结点前加入了dummy结点,省去了删除第一个结点的判断
  • 因为不存在索引越界,所以也无需判断最后一个结点
  • 第二个指针指向要删除结点的前一个结点,这样可以直接实现删除
posted @ 2021-02-01 10:59  一天到晚睡觉的鱼  阅读(50)  评论(0)    收藏  举报