删除链表的倒数第 N 个结点
难度:
标签:
题目描述
给你一个链表,删除链表的倒数第 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
进阶:你能尝试使用一趟扫描实现吗?
代码结果
运行时间: 48 ms, 内存: 16.9 MB
// 使用Java Stream的题解代码和注释
// 思路:由于Java Stream不直接支持链表的处理,我们可以使用Stream进行辅助计算。首先将链表转化为列表,然后通过列表的操作来处理倒数第n个元素的删除,最后再转化回链表。
import java.util.List;
import java.util.ArrayList;
import java.util.stream.IntStream;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
List<ListNode> nodeList = new ArrayList<>();
ListNode current = head;
while (current != null) {
nodeList.add(current);
current = current.next;
}
int removeIndex = nodeList.size() - n;
if (removeIndex == 0) {
return head.next; // 删除头节点
}
ListNode previous = nodeList.get(removeIndex - 1);
previous.next = previous.next.next;
return head;
}
}
解释
方法:
该题解使用了快慢指针的方法。首先让快指针先走 n 步,然后快慢指针同时向前移动,直到快指针到达链表尾部。此时慢指针指向的就是倒数第 n 个节点的前一个节点,把慢指针的 next 指针指向 next.next,即可删除倒数第 n 个节点。特殊情况是如果快指针走了 n 步后为 None,说明要删除的是头节点,直接返回 head.next 即可。
时间复杂度:
O(m),其中 m 为链表的长度
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在快慢指针策略中,让快指针先行n步而不是其他步数?
▷🦆
快指针在走完n步之后如果到达了None,这是如何确保删除的是头结点而不是其他节点的?
▷🦆
慢指针为什么要指向倒数第n个节点的前一个节点,直接操作倒数第n个节点不可以吗?
▷🦆
你在代码中如何处理特殊情况,例如链表长度等于1或者n等于链表长度的情况?
▷🦆
该算法的空间复杂度为O(1),能否详细解释为什么使用的空间不随链表大小变化?
▷🦆
如果在某个测试用例中快慢指针方法失败了,你会怎样调试或检查问题所在?
▷