zoukankan      html  css  js  c++  java
  • 链表判环问题

    给定一单链表的头指针head

    1、判断链表是否又环。

    2、如果有环,求环长以及环的起始节点。

    package aglist;
    
    class Node{
        public final int value;
        public Node next = null;
        Node(int value){
            this.value = value;
        }
        public static void addTail(Node head,Node node){
            Node temp = head;
            while(temp.next != null){
                temp = temp.next;
            }
            temp.next = node;
        }
        public static Node getNode(Node head,int index){
            int i = 0;
            Node temp = head;
            while(i < index && temp.next != null){
                temp = temp.next;
                i++;
            }
            return temp;
        }
        public static Node getTail(Node head){
            Node temp = head;
            while(temp.next != null){
                temp = temp.next;
            }
            return temp;
        }
    }
    public class Circle {
        public static boolean hasCircle(Node head){
            Node fast = head,slow = head;//两指针,一个步长为1,一个步长为2
            while(fast.next != null && fast.next.next != null){
                slow = slow.next;
                fast = fast.next.next;
                if(fast == slow){return true;}//两指针相遇,必有环,且相遇点在环内
            }
            return false;
        }
        private static Node getMeetNode(Node head){
            Node fast = head,slow = head;
            while(fast.next != null && fast.next.next != null){
                slow = slow.next;
                fast = fast.next.next;
                if(fast == slow){break;}
            }
            return fast;
        }
        private static int getLengthOfCircle(Node meetNode){
            int length = 1;
            Node temp = meetNode.next;
            while(temp != meetNode){//由于相遇点必在环内,只要顺着环走一圈,即可获得环的长度
                length++;
                temp = temp.next;
            }
            return length;
        }
        /*
         * 在相遇点将环分开,视为形成两个单链表
         * 一个单链表以head为头
         * 另一个单链表以meetNode为头
         * 该问题进而规约为求两个单链表的交点,交点即为环的起点
         * 并且其交点到两链表头等长
         * */
        private static Node getStartOfCircle(Node head,Node meetNode){
            while(head != meetNode){
                head = head.next;
                meetNode = meetNode.next;
            }
            return meetNode;
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            try {
                int[] ary = {3,4,5,7,1,40,10,50};
                Node head = new Node(30);
                for (int i = 0; i < ary.length; i++) {
                    Node.addTail(head, new Node(ary[i]));
                }
                Node.getTail(head).next = Node.getNode(head, 0);
                if (hasCircle(head)) {
                    Node meetNode = getMeetNode(head);
                    int lenght = getLengthOfCircle(meetNode);
                    Node start = getStartOfCircle(head, meetNode);
                    System.out.println("length:"+lenght);
                    System.out.println("StartNode:"+start.value);
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    
    }
  • 相关阅读:
    MySQL中的用户与授权
    Vim安装使用和配置
    Mysql中的explain和desc
    array_map、array_walk、array_reduce
    PHP二维数组去重(指定键名)
    git配置ssh秘钥(公钥以及私钥)windows
    在nginx上用FastCGI解析PHP
    关于token登录逻辑分析
    公有云 私有云 混合云 的区别
    使用Docker在服务器上部署Ubuntu,本地传文件到docker
  • 原文地址:https://www.cnblogs.com/qcblog/p/7572090.html
Copyright © 2011-2022 走看看