一、题目描述
来源:力扣(LeetCode)
给你一个链表,删除链表的倒数第 n
**个结点,并且返回链表的头结点。
网络异常,图片无法展示
|
输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
- 1 <= sz <= 30
- 0 <= Node.val <= 100
- 1 <= n <= sz
进阶: 你能尝试使用一趟扫描实现吗?
二丶思路分析
在删除节点的时候,我们需要知道节点的长度才能确定倒数第n个节点的位置。
如果遍历一次,在查找一次,也能做到。题目进阶的要求是尝试一次扫描来实现。
那么如果一次扫描来实现我们可以借助于类似窗口的概念来实现
- 这个窗口我们让它是定长
n
的一个窗口, - 窗口左边为链表的起点。
- 然后移动这个窗口,当窗口右边移动到链表的末端节点时候为空时候,窗口的左边指向的即是要被删除的 倒数第
n
个节点
如示例 1
网络异常,图片无法展示
|
三、代码实现
/** * 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 R = head; ListNode L = dummy; for (int i =0; i < n; ++i) { R = R.next; } while (R != null) { R = R.next; L = L.next; } L.next = L.next.next; ListNode res = dummy.next; return res; } }
复杂度分析
- 时间复杂度:
网络异常,图片无法展示|
n
是链表的长度 - 空间复杂度:
网络异常,图片无法展示|
运行结果
网络异常,图片无法展示
|
总结
这个题目也是利用双指针 + 窗口都类似概念(定长的)
,利用这个窗口的长度和移动,来确定倒数第n
个节点所在的位置。来达到一次的遍历实现。