LeetCode 算法19.删除链表的倒数第N个节点

问题

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?

示例

给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.

自解

思路

先进行一趟扫描将链表倒置,再进行第二趟扫描将指定节点删除。

代码

class Solution {
	public ListNode removeNthFromEnd(ListNode head, int n) {
        if (head == null)
            return null;
        if (head.next == null)
            return null;
        head = invert(head);
        ListNode temp = head;
        int count = 0;
        if (n == 1) {
            head = head.next;
        } else {
            while (true && temp != null) {
                count++;
                if (count == n - 1) {
                    temp.next = temp.next.next;
                    break;
                }
                temp = temp.next;
            }
        }
        head = invert(head);
        return head;
    }
    public ListNode invert(ListNode head) {
        ListNode ln = new ListNode(head.val);
        head = head.next;
        while (head != null) {
            ListNode temp = new ListNode(head.val);
            temp.next = ln;
            ln = temp;
            head = head.next;
        }
        return ln;
    }
}

结果

在这里插入图片描述
时间复杂度O(n)

进阶

官方解思路

上述算法可以优化为只使用一次遍历。我们可以使用两个指针而不是一个指针。第一个指针从列表的开头向前移动 n+1n+1 步,而第二个指针将从列表的开头出发。现在,这两个指针被 nn 个结点分开。我们通过同时移动两个指针向前来保持这个恒定的间隔,直到第一个指针到达最后一个结点。此时第二个指针将指向从最后一个结点数起的第 nn 个结点。我们重新链接第二个指针所引用的结点的 next 指针指向该结点的下下个结点。

作者:LeetCode
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-by-l/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

自写代码

public class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if (head == null)
            return null;
        if (head.next == null)
            return null;
        ListNode first = head;
        for (int i = 0; i < n; i++) {
            first = first.next;
        }
        if (first == null) {
            return head.next;
        }
        else {
            ListNode second = head;
            while (first.next != null) {
                first = first.next;
                second = second.next;
            }
            second.next = second.next.next;
        }
        return head;
    }
}

结果

在这里插入图片描述
时间复杂度O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值