Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
来源:力扣(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个节点所在的位置。来达到一次的遍历实现。