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;
}
}