leetcode19: 删除链表的倒数第N个节点
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
输入: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
进阶:你能尝试使用一趟扫描实现吗?
思路1 :使用栈
将链表遍历一遍,放入栈中。然后将栈里面的元素出栈,找到倒数第N+1个元素,删除倒数第N个元素。(如果倒数第N+1个为空,说明倒数第N个元素为head)。
public ListNode removeNthFromEnd(ListNode head, int n) { if(head == null){ return null; } Stack<ListNode> stack = new Stack<>(); ListNode p = head; while(p!=null){ stack.push(p); p = p.next; } //找到第N个元素 删除第N个 需要找到倒数第N+1个 for(int i = 0 ;i <n;i++){ stack.pop(); } //如果此时栈为空,则说明倒数第N个是链表第一个元素 if(stack.isEmpty()){ return head.next; } p = stack.pop(); p.next = p.next.next; return head; } 解答成功: 执行耗时:1 ms,击败了7.19% 的Java用户 内存消耗:37.8 MB,击败了5.04% 的Java用户
思路2 :使用双指针的思想
删除倒数第N个元素,必须找到链表中倒数第N+1
个节点。
使用start和end两个指针,将start放到第一个元素,end放到倒数第N+1个元素上。(需要考虑到倒数第N个元素是head的情况,这种情况end为null)。
将start和end同时往后移动,当end位于最后一个元素时,start刚好位于倒数第N+1个元素的位置。
注: 或者给链表添加一个头节点,就不需要考虑倒数第N个元素的特殊情况
public ListNode removeNthFromEnd(ListNode head, int n) { //删除倒数第N个 需要找到倒数第N+1个 ListNode start,end; start = head; end = head; for(int i = 0 ; i < n ;i++){ end = end.next; } //如果倒数第N个是head 此时end为null if(end == null){ return head.next; } //倒数第N个不是head, 此时start是第一个元素 end是第N+1个元素 //将他们同时向后移动 当end在最后一个元素时,start刚好是倒数第N+1个元素 while(end.next!=null){ start = start.next; end = end.next; } //删除倒数第N个元素 start.next = start.next.next; return head; } 执行耗时:执行耗时:0 ms,击败了100.00% 的Java用户 内存消耗:36.4 MB,击败了55.15% 的Java用户