判断一链表是否有环,求环的第一个节点和环的长度

第一种方法:直接遍历时,用hashset存放,判断是否存在环

第二种方法:使用快慢指针

public class CycleLinkedList {

    public static void main(String[] args) {

        Node head = new Node(1);
        Node node3 = new Node(3);
        head.next = node3;
        head.next.next = new Node(5);
        head.next.next.next = new Node(7);
        head.next.next.next.next = new Node(9);
        head.next.next.next.next.next = node3;
        System.out.println("是否有环:" + hasCycle(head));
        Node enterNode = getEnterNode(head);
        System.out.println("环的入口:" + enterNode.value);
        System.out.println(getCycleSize(enterNode));

    }

    // 环的长度
    public static Integer getCycleSize(Node node) {
        Node start = node;
        int len = 1;
        while (node.next != start) {
            len++;
            node = node.next;
        }
        return len;
    }

    // 如果有环的话,慢指针和快指针一定会在环上的某个点相遇,但不一定是环的入口
    public static boolean hasCycle(Node head) {
        Node fast = head;
        Node slow = head;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast) {
                return true;
            }
        }
        return false;
    }

    // 环的入口节点
    public static Node getEnterNode(Node head) {
        // 先求出快慢指针的相遇点
        Node fast = head;
        Node slow = head;
        Node cross = null;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast) {
                cross = fast;
                break;
            }
        }
        // 从链表头部和相遇点开始,每次移动一个节点,他们相遇点就是环的入口
        Node start = head;
        while (start != null && cross != null) {
            if (start == cross) {
                return cross;
            }
            start = start.next;
            cross = cross.next;
        }
        return null;
    }

    public static class Node {

        Node next;
        int value;

        public Node(int value) {
            super();
            this.value = value;
        }
    }
}

原文地址:https://www.cnblogs.com/moris5013/p/11640652.html

时间: 2024-10-17 14:25:21

判断一链表是否有环,求环的第一个节点和环的长度的相关文章

<笔试><面试>C/C++单链表相关(4)判断两链表是否相交,求交点(链表不带环/可能带环)

判断两链表是否相交,求交点(假设链表不带环) 判断两链表是否相交,求交点(假设链表可能带环) RingEntry_Point()等函数见前篇. SListNode* Intersect(SListNode *&L, SListNode *&M)//判断两链表是否相交,求交点(假设链表不带环) {  //思路:若不带环,只有相交/不想交两种情况  // 与RingEntry_Point()函数方法相同:  //     求两个链表长度之差K,再令一个指针从长链表开始先走K步,令另一个指针从短

判断两链表是否相交,如果相交找到第一个交点

#include <stdio.h> #include <stdlib.h> typedef struct LinkNode { struct LinkNode* next; int data; }LinkList; /*说明:都带头结点的单链表*/ /*创建链表*/ void createLinkList(LinkList* head, int* a, int n) { int i = 0; LinkNode* node = NULL; while (i < n) { no

笔试,面试,C/C++,判断单链表是否带环?若带环,求环长度,求环入口点(两种方法)

SListNode* IsRing(SListNode *&pHead) //判断链表是否有环,求相聚点 {  //判空.有.没有  //思路:两个指针从头开始一快(2步)一慢(1步),若最后可以相聚,则链表有环  if (pHead)  {   SListNode *fast = pHead;   SListNode *slow = pHead;   while (fast&&fast->next)   {    fast = fast->next->next;

判断单向链表是否有环,环起点,环长,链表长

今天在微信上看到一篇介绍如何判断单向链表是否有环的文章,感觉很有意思,整理一下读后的思路. 一.判断单向链表是否有环 方法1:设置一个Hashset,顺序读取链表中的节点,判断Hashset中是否有该节点的唯一标识(ID).如果在Hashset中,说明有环:如果不在Hashset中,将节点的ID存入Hashset. 这种方法时间复杂度已经最优,但是因为额外申请了Hashset,所以空间复杂度不算最优. 方法2:设置2个指针,指向头节点.第1个指针每次指向下一个节点:第2个指针指向下一个节点的下一

如何判断单链表是否存在环

原文:http://blog.csdn.net/liuxialong/article/details/6555850 如何判断单链表是否存在环 给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,

如何判断单链表是否存在环 &amp; 判断两链表是否相交

给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,slow.fast从该点开始,再次碰撞所走过的操作数就是环的长度s. 3.问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分

判断单链表是否有环相关问题(转载加总结)

给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,slow.fast从该点开始,再次碰撞所走过的操作数就是环的长度s. 3.问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分

数据结构和算法设计专题之---判断单链表中是否有环,环的长度,环的入口节点

题目: 给定一个单链表,只给出头指针head: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,slow.fast从该点开始,再次碰撞所走过的操作数就是环的长度s. 3.问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的

判断单链表里面有没有环

原文链接:http://www.cnblogs.com/zhyg6516/archive/2011/03/29/1998831.html 这题目还是挺有意思的. 题目:0.如何判断单链表里面是否有环? 算法的思想是设定两个指针p, q,其中p每次向前移动一步,q每次向前移动两步.那么如果单链表存在环,则p和q相遇:否则q将首先遇到null. 这里主要理解一个问题,就是为什么当单链表存在环时,p和q一定会相遇呢? 假定单链表的长度为n,并且该单链表是环状的,那么第i次迭代时,p指向元素i mod