这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
⚽题目
给你一个链表,删除链表的倒数第 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]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
⚽一点点思路
我相信这种题要是普通的没有这一句**你能尝试使用一趟扫描实现吗?**我觉得大家做出来都没问题。别说有问题有问题的话回到专栏自己在把以前的题再做一下,那么加上这一句我们该怎么做呢?我想要是能知道链表长度就好了做起来非常简单,但是得到链表长度不是还要遍历一次吗,然后才能得到倒数第n个。所以这里我们要发散思维了
- 1·第一种方法:构造双指针两个指针的间隔为n当最后一个到达尾部后一个正好在倒数第n个
- 2·第二种:如果你觉得第一种有点钻空子的话,第二种可以把链表的一个一个遍历然后放入栈里面,弹出的第n个就是要删除的。
阿肥就是用这种方法做的
⚽开干
⚽介绍一种函数Deque
Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋壳。
Deque 继承自 Queue,直接实现了它的有 LinkedList, ArayDeque, ConcurrentLinkedDeque 等。
Deque 支持容量受限的双端队列,也支持大小不固定的。一般双端队列大小不确定。
Deque 接口定义了一些从头部和尾部访问元素的方法。比如分别在头部、尾部进行插入、删除、获取元素。和 Queue
Deque 的实现类主要分为两种场景:
一般场景
LinkedList 大小可变的链表双端队列,允许元素为 null
ArrayDeque 大下可变的数组双端队列,不允许 null
并发场景
LinkedBlockingDeque 如果队列为空时,获取操作将会阻塞,知道有元素添加
那么既然Deque继承了Queue接口那么它肯定能做队列吧,今天我们只说它做栈的用法,都说篇幅太长了。这里有一些它做栈的方法
⚽源码和详解
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//先建立一个新的节点指向头节点
ListNode dummy = new ListNode(0, head);
//建立栈
Deque<ListNode> stack = new LinkedList<ListNode>();
//这算是一个游标变量用来遍历链表的
ListNode cur = dummy;
//将链表的节点全部入栈
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
//出栈到第n以前
for (int i = 0; i < n; ++i) {
stack.pop();
}
下面就是将n的前一个节点链接到n的下一个
ListNode prev = stack.peek();
prev.next = prev.next.next;
ListNode ans = dummy.next;
return ans;
}
}
好了今天的算法就到这里了,我们明天见喽 :)