力扣
package Algorithms;
import java.util.List;
/**
* @author : zhang
* @version : 1.0
* @date : Create in 2021/7/31
* @description :
*/
public class RemoveNthFromEnd {
public static void main(String[] args) {
ListNode list1 = new ListNode(1);
ListNode list2 = new ListNode(2);
ListNode list3 = new ListNode(3);
ListNode list4 = new ListNode(4);
SingleList singleList = new SingleList();
singleList.add(list1);
singleList.add(list2);
singleList.add(list3);
singleList.add(list4);
System.out.println("原链表为:");
singleList.list();
//删除倒数第2个节点3
ListNode listNode = removeNthFromEnd_2(singleList.getHead(), 2);
System.out.println("删除后的链表为:");
singleList.list();
}
//获取单链表节点的个数
public static int getLength(ListNode head) {
int length = 0;
ListNode cur = head;
while (cur.next != null) {
length++;
cur = cur.next;
}
return length;
}
//删除倒数第N个节点
//方式1:查找出倒数第N+1个节点
public static ListNode removeNthFromEnd_1(ListNode head, int n) {
if (head == null) {
return null;
}
int size = getLength(head);
if (n <= 0 || n > size){
return null;
}
//for循环定位到倒数第N+1个节点
// head -> 1 -> 2 -> 3 -> 4 size = 4, cur = head
// 倒数第N+1个节点需要遍历的次数为:size-N+1 比如:需要删除倒数第N = 2个节点 3 ,
// 需要找到它的前一个节点2,遍历的次数为4-2=2次,
ListNode cur = head;
for (int i = 0; i < size-n; i++) {
cur = cur.next;
}
//退出循环后就找到了倒数第N+1个节点,然后删除倒数第N个节点
cur.next = cur.next.next;
return head;
}
//删除倒数第N个节点
//方式2:通过双指针(first、second)的方式进行删除
//first比second超前n个节点,当first遍历到链表的末尾时,second就恰好是倒数第n个节点
//1、first 和second指向头结点(这里的头节点不存放任何数据,相当于dummy),首先使用first对链表进行遍历n次
//2、同时使用first和second对链表进行遍历,当first遍历到链表末尾时,second就恰好是倒数第n个节点
//注:遍历的时候考虑second指向倒数第N个节点的前一个节点有助于我们删除
public static ListNode removeNthFromEnd_2(ListNode head, int n) {
ListNode first = head.next;
ListNode second = head;
for (int i = 0; i < n; i++) {
first = first.next;
}
//for循环结束后,first和second之间相隔n个元素,然后对first和second同时进行遍历,
//当first指向链表末尾时,second指向倒数第n个节点的前驱节点
while (first != null){
first = first.next;
second = second.next;
}
second.next = second.next.next;
return head;
}
}
//定义SingleList,来管理ListNode
class SingleList {
//初始化一个头节点,不存放任何数据
private ListNode head = new ListNode(0);
public ListNode getHead() {
return head;
}
//添加节点到单向链表中
public void add(ListNode listNode) {
ListNode temp = head;
while (true) {
if (temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = listNode;
}
//显示单向链表
public void list() {
if (head.next == null) {
System.out.println("链表为空!");
return;
}
ListNode temp = head.next;
while (true) {
if (temp == null) {
break;
}
System.out.println(temp);
temp = temp.next;
}
}
}
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
@Override
public String toString() {
return "ListNode{" +
"val=" + val +
'}';
}
}