LeetCodeHot 100 必刷必会 - 019 删除链表的倒数第 N 个结点
地址:19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
题目描述:
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
思路:
如何判断当前结点是倒数第N个结点呢?
1、 一次遍历获取链表长度。
2、 获取待删除节点所在位置。
3、遍历到该位置,直接将当前指针指向下一个。
代码:
解法一:
/**
* 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(0, head);
ListNode nodeTmp = dummy;
int length = 0;
// 一次遍历获取链表长度
while (head != null) {
length++;
head=head.next;
}
// 倒数第一个 等于正数最后一个
int num = length - n + 1;
// 二次遍历获取删除结点 遍历循环要从1开始
for (int i = 1; i < num; i++) {
nodeTmp = nodeTmp.next;
}
// nodeTmp.next 就是要删除的结点,直接将其替换成下一个结点
nodeTmp.next = nodeTmp.next.next;
return dummy.next;
}
}
解法二(双指针法)
思路:双指针就是通过快慢指针进行遍历,快指针先出发,慢指针后出发,中间相差的就是n,当快指针到达终点时,慢指针刚好到达需要删除的节点。
代码:
/**
* 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(0, head);
// 快指针 先出发
ListNode quickPointer = head;
ListNode slowPointer = dummy;
while (quickPointer != null) {
if (n == 0) {
// 慢指针等快指针出发n步后开始出发
quickPointer = quickPointer.next;
slowPointer = slowPointer.next;
} else {
quickPointer = quickPointer.next;
n--;
}
}
slowPointer.next = slowPointer.next.next;
return dummy.next;
}
}