leetcode19. 删除链表的倒数第N个节点(最详细解法,执行时间1ms)

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

示例:

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

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

说明:

给定的 n 保证是有效的。

进阶:

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

这道题的是要倒数删除第n个结点并返回删除后的链表,有就是返回该链表的头指针。

  • 我们用正常的思路考虑的话,删除倒数第几个结点,就得找到正向顺序的该结点,
  • 那么要找到正向的该结点,就必须知道该链表的长度,所以就需要遍历一遍该链表。
  • 知道链表的长度后,我们又得遍历一遍该表找到要删除的结点,所以至少得遍历两边该表,这样的话,程序的时间复杂度就会大大增加。
  • 那么如何做到题目的要求尝试一趟扫描呢?

题目要的是删除倒数第n个结点,我们首先要做的是找到这个结点的前驱,我们可以这样想,倒数第n个结点离表尾的距离是多少呢?我们从这个距离差可以出发。定义两个快慢指针,让他两之差等于删除的这个结点到表尾的距离之差。在这里插入图片描述

我们让fast指针先从头走n步,也就是距离之差步,然后让slow指针再从头开始走,此时两者之差就是删除的结点到表尾的距离,然后让两者同时出发,当fast走到表尾的时候,slow刚好走到要删除的结点的前驱,这样就找到了我们要删除的结点。

****这里我们得考虑这样一种情况,如果表长为5,我们要删除倒数第5个结点,其实就是删除正向的第一个结点,直接返回head.next就ok!!!具体代码如下:

`

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head==null||head.next==null){
            return null;
        }
        ListNode fast=head;
        ListNode slow=head;
        for(int i=0;i<n;i++){
                fast=fast.next;
            }
        if(fast==null){
                return head.next;
            }
        while(fast.next!=null){
            fast=fast.next;
            slow=slow.next;            
        }
        slow.next=slow.next.next;
        return head;
    }
}

执行结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42405666/article/details/88937398
今日推荐