描述
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1,2], n = 1
输出:[1]
思路
1、本题的本质是删除链表中某个位置的结点,通过循环将指针移到待删除指针的前一个指针,涉及到浅拷贝以及头节点不能移动的问题,所以用临时变量temp储存。
2、遍历链表,得到有效的链表长度,链表长度-n 就是待删除位置的前一个节点
3、考虑到可能删除的是头节点,所以用pre节点表示头节点的前驱节点,pre节点的next节点是head节点。
4、最后删除用temp.next=temp.next.next,结果返回pre.next
代码
package algorithm;
/**
* @author taoke
* @desc 删除链表指定的节点
* @email 1504806660@qq.com
* @date 2022/2/8
*/
public class RemoveNthFromEnd {
public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
head.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
RemoveNthFromEnd nth = new RemoveNthFromEnd();
ListNode fromEnd = nth.removeNthFromEnd(head, 2);
System.out.println(fromEnd);
}
public static class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
/**
* 移除倒数第n个节点
*
* @param head 头节点
* @param n 倒数第n个节点
* @return 头节点
*/
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = new ListNode(0);
pre.next = head;
ListNode temp = pre;
for (int i = 0; i < size(head) - n; i++) {
temp = temp.next;
}
if (temp.next != null) {
temp.next = temp.next.next;
}
return pre.next;
}
/**
* 获取有效节点数量
*
* @return 有效节点数量
*/
public int size(ListNode head) {
ListNode temp = head;
if (temp.next == null) {
return 0;
}
int size = 1;
while (temp.next != null) {
size++;
temp = temp.next;
}
return size;
}
}