1.题目
给定一个链表,删除链表的倒数第n个节点,并且返回链表的头节点
2.示例
给定一个链表:1 -> 2 -> 3 -> 4 -> 5
删除位置:n=2,n必须是有效的位置
删除倒数第2个节点后的链表:1 -> 2 -> 3 -> 5
3.图示
4.分析
(1)首先创建三个指针pre,slow,fast,pre指向第一个节点的前驱节点,slow和fast指针指向第一个节点
(2)先让fast指针向前移动n步
(3)然后pre,slow,fast三个指针一起向前移动,当fast指针指向最后一个节点的后继节点时,slow指针指向的就是要删除的倒数第n个节点,pre用来记住后一个节点的位置
(4)此时,让pre->next = slow->next
5.代码实现
package com.company.algorithm;
public class DeleteKthLastNodeInLinkedList {
public static void main(String[] args) {
// write your code here
LinkNode linkNode = createLink(new int[]{1, 2, 3, 4, 5});
System.out.println(printLink(linkNode));
System.out.println(printLink(deleteKthLastNodeInLinkedList(linkNode, 5)));
}
/**
* @param head 头节点
* @param k 要删除节点的位置
* @return 删除后新链表的头节点
*/
private static LinkNode deleteKthLastNodeInLinkedList(LinkNode head, int k) {
if (k <= 0 || head == null) return head;
LinkNode pre = null;
LinkNode fast = head;
LinkNode slow = head;
while (k-- != 0) {//fast指针先向前移动k个节点
if (fast != null) fast = fast.nextNode;
else return head;
}
while (fast != null) {//fast和slow同步向前移动k个节点
pre = slow;//pre在slow的前一个节点
slow = slow.nextNode;
fast = fast.nextNode;
}
if (pre != null) pre.nextNode = slow.nextNode;
else head = slow.nextNode;//边界值处理-删除倒数最后一个节点
return head;
}
//创建链表
private static LinkNode createLink(int[] data) {
LinkNode head = new LinkNode(data[0]);
LinkNode temp = head;
for (int i = 1; i < data.length; i++) {
LinkNode linkNode = new LinkNode(data[i]);
temp.nextNode = linkNode;
temp = linkNode;
}
return head;
}
//打印链表
private static String printLink(LinkNode head) {
String str = "";
while (head != null) {
str += head.value;
head = head.nextNode;
if (head != null) str += " -> ";
}
return str;
}
}
//节点类
class LinkNode {
public int value;
public LinkNode nextNode;
public LinkNode(int value) {
this.value = value;
}
}