zoukankan      html  css  js  c++  java
  • 删除链表倒数第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 +
                    '}';
        }
    }
  • 相关阅读:
    Java应用开发中的SQL注入攻击
    TOSCA自动化测试工具ppt
    SQL Server怎么备份数据库
    翻翻git之---一个丰富的通知工具类 NotifyUtil
    ZOJ
    高速掌握Lua 5.3 —— Lua与C之间的交互概览
    poj1649 Rescue(BFS+优先队列)
    面向对象在JavaScript中的接口实现
    dedecms织梦后台password忘记了怎么办?dedecms织梦后台password忘记怎样找回password?
    [ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和或者矩阵转化)
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/15083763.html
Copyright © 2011-2022 走看看