难度:medium
Java:
双指针:
/**
* 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(-1, head);
//设置快慢指针,快指针比慢指针领先 n+1 个节点
ListNode fast = dummy;
ListNode slow = dummy;
n++;
while (n-- != 0) {
fast = fast.next;
}
//快慢指针同时移动。当fast == null时,slow.next所指即为要删除的元素
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
复杂度分析:
- 时间复杂度:O(L),其中 L是链表的长度
- 空间复杂度:O(1)
栈:
利用栈的先进后出的原理,现将链表的所有元素入栈,然后出栈即从末尾开始寻找删除的节点;
//栈
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1, head);
//stack
Deque<ListNode> stack = new LinkedList<>();
//入栈:虚拟头结点也要入栈
ListNode cur = dummy;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
//出栈:dele即为所删除的节点
ListNode dele = new ListNode();
while(n-- != 0) {
dele = stack.pop();
}
ListNode pre = stack.peek();
//绕过dele节点
pre.next = dele.next;
//释放dele节点的next指针
dele.next = null;
return dummy.next;
}
}
复杂度分析
- 时间复杂度:O(L),其中 L是链表的长度
- 空间复杂度:O(L),其中 L是链表的长度;主要为栈的开销
nice