删除链表倒数第N个节点
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 + '}'; } }