删除链表中倒数第N个节点_19
19. 删除链表的倒数第 N 个结点:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
给你一个链表,删除链表的倒数第
n
个结点,并且返回链表的头结点。/* 1.借助栈实现 解题思路: 1.通过遍历将所有的节点入栈 2.通过for循环,弹出栈顶元素,弹出n个元素,就是需要删除的节点, 3.此时栈顶的节点就是待删除节点的前驱节点。 */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0, head); Deque<ListNode> stack = new LinkedList<>(); ListNode cur = dummy; while (cur != null) { stack.push(cur); cur = cur.next; } for(int i=0; i<n; i++){ stack.pop(); } ListNode prev = stack.peek(); prev.next = prev.next.next; return dummy.next; } } 复杂度分析: 时间复杂度:O(L),其中 L 是链表的长度。 空间复杂度:O(L),其中 L 是链表的长度。主要为栈的开销。 /* 2.通过计算链表长度 解题思路: 1.第一次遍历得到链表的长度L 2.再从头遍历,遍历到L-n+1个节点时,就是要删除的节点 3.为了方便操作,定义虚拟头结点dummy,以及工作指针prev 3.1 同样遍历 L - n + 1,此时下一个节点就是要删除的节点 4.结果返回dummy.next即可 */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0, head); int length = getLength(head); ListNode cur = dummy; for (int i = 1; i < length - n + 1; ++i) { cur = cur.next; } cur.next = cur.next.next; ListNode ans = dummy.next; return ans; } public int getLength(ListNode head) { int length = 0; while (head != null) { length++; head = head.next; } return length; } } /* 3.双指针 解题思路: 1.定义两个指针p,q,都指向head 2.让p指针先走n步 3.之后p,q同时走,保持两者的距离相差为n. 4.当 p 遍历到链表的末尾(即 p 为空指针)时,q 恰好指向倒数第 n 个节点。 4.1.为了删除方便,将q指针指向虚拟头结点,其余操作不变 4.2这样一来,当 p 遍历到链表的末尾时,q 的下一个节点就是我们需要删除的节点。 */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0, head); ListNode first = head; ListNode second = dummy; for (int i = 0; i < n; ++i) { first = first.next; } while (first != null) { first = first.next; second = second.next; } second.next = second.next.next; ListNode ans = dummy.next; return ans; } } 4.递归 class Solution { int cur = 0; public ListNode removeNthFromEnd(ListNode head, int n) { if (head == null) return null; head.next = removeNthFromEnd(head.next, n); return ++cur == n ? head.next : head; } } /* 5.使用map实现 解题思路: 1.map第一个参数为节点的位置 2.index初始化为1,则index++ index初始化为0,则++index 3.当map.size() == 1,则删除后,没有节点了,肯定返回null. 4.当n==map.size(),表示要删除头结点,直接返回head.next. 5.当n==1,表示要删除最后一个节点,则让map.get(map.size()-1).next=null,置空最后一个节点 6.当n位于中间时,则定位n的前一个结点.next,指向n+1位置节点 */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { Map<Integer, ListNode> map = new HashMap<>(); ListNode tmp = head; int index = 1; while(tmp != null){ map.put(index++, tmp); tmp = tmp.next; } if(map.size() == 1) { return null; } if(n == map.size()) { return head.next; } else if(n == 1){ map.get(map.size()-1).next = null; } else{ map.get(map.size()-n).next = map.get(map.size()-n+2); } return head; } }
分类:
Leetcode
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix