数据结构与算法(删除链表的倒数第n个结点)

原题

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

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

示例 1:

数据结构与算法(删除链表的倒数第n个结点)_第1张图片

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]

解答

定义一个虚拟头结点virtual(设置虚拟头节点,为了方便对所有结点统一进行操作,而不需要对head结点采用额外的处理),定义快指针fast和慢指针slow,由于需要删除倒数第n个结点,让fast先走n步,然后再和slow一起开始遍历,这样可以在fast和slow之间形成一个大小为n的窗口。但是由于while循环的终止条件,我们需要等到fast=null的时候才能知道链表已经遍历到末尾。以1-2-3-4这个链表,删除倒数第2个结点为例,当fast走到null时,slow刚好到倒数第n个结点3的位置,但是fast和slow之间形成的窗口(4,null)并不是我们想要的窗口,因为要删除结点3,就得让slow位于结点2的位置,所以我们需要fast比slow先走n+1步,然后slow和fast才一起往下遍历,等到fast走到null,slow的位置刚好在结点2的位置,此时形成的窗口为(3,4,null),倘若忽略null的存在,窗口(3,4)正好大小为n

/**
 * 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 virtual=new ListNode();
        virtual.next=head;
        ListNode slow=virtual;
        ListNode fast=virtual;
        int count=0;
        n++;
        while(count!=n){//fast先走n+1步
            fast=fast.next;
            count++;
        }
        while(fast!=null){//fast和slow一起往下遍历
            fast=fast.next;
            slow=slow.next;
        }
        slow.next=slow.next.next;
        return virtual.next;
    }
}

你可能感兴趣的:(算法笔记,链表,数据结构)