解题代码参考链接:解题
-
问题描述
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.说明:给定的 n 保证是有效的。进阶:你能尝试使用一趟扫描实现吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list -
分析
由于事先不知到链表的长度,如果去求链表的长度的话,则需额外遍历一次,而题目最好要求是一次遍历。遍历一次的话,可以用双指针(快指针p,慢指针q),p先走n步,然后q再出发,当p走到尽头的时候,恰好位于倒数第n个位置上。解题参考源码:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/hua-jie-suan-fa-19-shan-chu-lian-biao-de-dao-shu-d/
另外,在Java中有垃圾回收机制,所以我们可以不用去手动释放所要删除的节点,但若是在C++中则需要手动释放。 -
代码
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//p为快指针,让p先走n步(边走并判断链表长度)
ListNode p = head;
//p所经过链表长度
int len;
for (len = 0; len < n; len++) {
p = p.next;
if (p == null) {
break;
}
}
//链表长度为n时,删除头结点,返回head.next(null)
if (len == n - 1) {
return head.next;
}
//链表长度小于n,则返回头节点
if (len < n - 1) {
return head;
}
//q为慢指针,当p走了n步后,p再出发
ListNode q = head;
//此时链表长度至少为n+1,且p正好指示第n+1个节点
while (p.next != null) {
p = p.next;
q = q.next;
}
q.next = q.next.next;
return head;
}
}
2019.12.02