day15 leetcode-hot100-29(链表8)
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
1.暴力法
思路
(1)先获取链表的长度L
(2)然后再次遍历链表到L-n的位置,直接让该指针的节点指向下下一个即可。
2.哈希表
思路
(1)将链表中所有节点都加入到哈希表中,其中哈希表的格式为HashMap<Integer,ListNode>,前面表示节点的位置,后面是节点。
(2)根据(1)可以知道链表的总长度nums,倒数第n个节点的位置为del=nums-n+1;
(3)然后取出del-1与del+1位置的节点,让del-1的下一个节点为del+1即可。
ps:需要考虑被删除的节点是否开头节点或者结尾节点。开头直接下一个,结尾直接del-1指向null即可。
具体代码
/*** 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 init = head;HashMap<Integer,ListNode> map =new HashMap<>();int count=0;while(head!=null){map.put(++count,head);head=head.next;}int nums=count;int del=nums-n+1;if(del==1){return init.next;}if(del==nums){if(nums==1){return new ListNode();}else{ListNode p1 = map.get(del-1);p1.next=null;return init;}}ListNode p1 = map.get(del-1);ListNode p2 = map.get(del+1);p1.next=p2;return init;}
}
3.栈
思路
(1)将全部节点入栈。
(2)然后用for循环弹出去n个节点,然后让最后的节点的next等于next.next
ps:初始化的时候设置一个空节点指向head,防止全部弹出去后next.next报错.
具体代码
/*** 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 init = new ListNode(0,head);Deque<ListNode> stack = new LinkedList<ListNode>();ListNode cur = init;while(cur!=null){stack.push(cur);cur=cur.next;}for(int i=0;i<n;i++){stack.pop();}ListNode n1 = stack.peek();n1.next=n1.next.next;return init.next;}
}
4.双指针
思路
设计快慢指针,其中快指针比慢指针多走n次,等快指针到null的时候,慢指针所在的位置就是要弹出的位置的前一个
ps:(1)其实多走了n+1步,因为需要慢指针走到要弹出位置的前一个节点。
(2)慢指针是0节点并指向第一个节点head,快指针一开始就指向head,这样就算长度为1的链表,slow慢指针的next.next也不会报错,否则出现空指针异常。
具体代码
/*** 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 init = new ListNode(0,head);ListNode fast = head;ListNode slow = init;for(int i=0;i<n;i++){fast=fast.next;}while(fast!=null){fast=fast.next;slow=slow.next;}slow.next=slow.next.next;return init.next;}
}