-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
leetcode19:删除链表倒数第 n 个结点 #16
Comments
快慢指针法 |
解法:快慢指针解题思路: 需要删除链表中的倒数第 步骤: 使用 2 个指针:
然后, 此时, 但存在一个问题,当链表长度为
解决方案一:添加 const removeNthFromEnd = function(head, n) {
let preHead = new ListNode(0)
preHead.next = head
let fast = preHead, slow = preHead
// 快先走 n+1 步
while(n--) {
fast = fast.next
}
// fast、slow 一起前进
while(fast && fast.next) {
fast = fast.next
slow = slow.next
}
slow.next = slow.next.next
return preHead.next
}; 解决方案二:单独处理倒数第 const removeNthFromEnd = function(head, n) {
let fast = head, slow = head
// 快先走 n 步
while(--n) {
fast = fast.next
}
if(!fast.next) return head.next
fast = fast.next
// fast、slow 一起前进
while(fast && fast.next) {
fast = fast.next
slow = slow.next
}
slow.next = slow.next.next
return head
}; 时间复杂度:O(n) 空间复杂度:O(1) |
瓶子君,不是很明白这里 slow.next = slow.next.next
return head 改变的是 |
因为题目要求在删除了指定节点后,需要返回的是链表的头结点。所以返回的是 |
new ListNode(0) 这个是什么 |
var removeNthFromEnd = function(head, n) {
const dump = new ListNode(-1)
dump.next = head
let fast = dump
let slow = dump
while (n--) {
fast = fast.next
}
while (fast.next) {
fast = fast.next
slow = slow.next
}
slow.next = slow.next.next
return dump.next
};
|
注释写的先走的步数是不是有问题? 第一种解法: n-- 先走 n 步, |
var removeNthFromEnd = function (head, n) {
// 哨兵节点
let dump = new ListNode();
dump.next = head;
// 快慢指针
let fast = slow = dump;
// 快指针先走n步
for (let i = 0; i < n; i++) {
fast = fast.next;
}
// 快指针走到最后,当前slow为倒数第n+1个节点
while(fast && fast.next) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dump.next;
}; |
借用数组存放链表节点 通过数组下标进行删除
}; |
快慢指针:
}; |
题目地址(19. 删除链表的倒数第 N 个节点)https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/ 题目描述
前置知识
公司
思路这里我们可以使用双指针算法,不妨设为指针 A 和 指针 B。指针 A 先移动 n 次, 指针 B 再开始移动。当 A 到达 null 的时候, 指针 B 的位置正好是倒数第 n。这个时候将 B 的指针指向 B 的下下个指针即可完成删除工作。 算法:
(图片来自: https://github.com/MisterBooo/LeetCodeAnimation) 关键点解析
代码代码支持: JS, Java,CPP Javascript Code: /**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function (head, n) {
let i = -1;
const noop = {
next: null,
};
const dummyHead = new ListNode(); // 增加一个dummyHead 简化操作
dummyHead.next = head;
let currentP1 = dummyHead;
let currentP2 = dummyHead;
while (currentP1) {
if (i === n) {
currentP2 = currentP2.next;
}
if (i !== n) {
i++;
}
currentP1 = currentP1.next;
}
currentP2.next = ((currentP2 || noop).next || noop).next;
return dummyHead.next;
}; Java Code: /**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
TreeNode dummy = new TreeNode(0);
dummy.next = head;
TreeNode first = dummy;
TreeNode second = dummy;
if (int i=0; i<=n; i++) {
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
} CPP Code: class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *p = head, *q = head;
while (n--) q = q->next;
if (!q) {
head = head->next;
delete p;
return head;
}
while (q->next) p = p->next, q = q->next;
q = p->next;
p->next = q->next;
delete q;
return head;
}
}; 复杂度分析
大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。 |
我自己用了递归回溯的方式,也是只扫描了一遍,虽然没有 const removeNthFromEnd = (head: Node | undefined, n: number) => {
if (n <= 0) return head;
if (!head) return head;
let result: Node | undefined = head;
const fn = (prev: Node | undefined, node: Node | undefined): number => {
if (!node) return 0;
const deep = fn(node, node.next) + 1;
if (deep === n) {
if (!prev) {
// 删除的head
result = node.next;
} else {
const nextNode = node.next;
prev.next = nextNode;
}
}
return deep;
};
fn(undefined, head);
return result;
}; |
你理解为slow和fast闭区间内的步数就可以了 |
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
附leetcode地址:leetcode
The text was updated successfully, but these errors were encountered: