Floyd's Tortoise and Hare 链表闭环判断算法

关于我的 Leetcode 题目解答,代码前往 Github:https://github.com/chenxiangcyr/leetcode-answers


Floyd算法分为两个不同的阶段。第一个阶段是判断在链表中是否有环路,如果不存在就马上返回空,也就不存在第二阶段。第二个阶段就是找到环路的入口。

第一阶段:
初始化两个指针(快的兔子hare)(慢的乌龟tortoise)。接下来,兔子hare和乌龟tortoise从同一个节点出发(头节点),乌龟tortoise每次走一个节点,兔子hare每次走两个节点。
如果他们在前进若干步后在同一个节点相遇,我们就返回这个节点,如果最终没有返回节点信息,而是返回空,则代表不存在环路。

第二阶段:
由于第一阶段确定了有环路,第二阶段就是找环的入口节点。接下来初始化两个个指针,ptr1:它指向头节点, ptr2:指向第一阶段找到的相遇节点
然后将他们以一次移动一个节点的速度向前移动,直到他们再次相遇为止,并返回这个节点。

LeetCode算法题:141. Linked List Cycle
Given a linked list, determine if it has a cycle in it.

    public boolean hasCycle(ListNode head) {
        if(head == null) {
            return false;
        }
        
        // two pointer strategy
        ListNode p1 = head;
        ListNode p2 = head;
        
        while(p2 != null && p2.next != null) {
            p1 = p1.next;
            p2 = p2.next.next;
            
            if(p1 == p2) {
                return true;
            }
        }
        
        return false;
    }

LeetCode算法题:142. Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

    public ListNode detectCycle(ListNode head) {
        if(head == null || head.next == null) {
            return null;
        }
        
        // two pointer strategy
        ListNode p1 = head;
        ListNode p2 = head;
        
        while(p2 != null && p2.next != null) {
            p1 = p1.next;
            p2 = p2.next.next;
            
            if(p1 == p2) {
                break;
            }
        }
        
        if(p1 != p2) {
            return null;
        }
        
        ListNode p = head;
        while(p != p2) {
            p = p.next;
            p2 = p2.next;
        }
        
        return p;
    }

LeetCode算法题:287. Find the Duplicate Number
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

    public int findDuplicate(int[] nums) {
        
        /*
        假设数组长度为5,则元素范围是 1~4
        */
        int n = nums.length;
        
        // Sorting algorithm: O(N*logN)
        /*
        Arrays.sort(nums);
        
        int result = nums[0];
        for(int i = 1; i < nums.length; i++) {
            if(result == nums[i]) {
                return result;
            }
            else {
                result = nums[i];
            }
        }
        
        return 0;*/
        
        // Floyd's Tortoise and Hare 链表闭环判断算法
        /*
        定义两个指针 p1,p2,根据当前的值向前跳动。
        由于数组中肯定有重复的元素,因此 p1 和 p2 肯定会相遇。
        */
        int p1 = nums[0];
        int p2 = nums[0];
        while(true) {
            p1 = nums[nums[p1]];
            p2 = nums[p2];
            
            if(p1 == p2) {
                break;
            }
        }
        
        int p = nums[0];
        while(p != p2) {
            p = nums[p];
            p2 = nums[p2];
        }
        
        return p;
    }

引用:
链表闭环判断(Floyd's Tortoise and Hare)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Cycle Detect 环检测算法常用检测链表是否有环,如果有环,给出环的长度和环的入口点。相关题目: 287....
    有苦向瓜诉说阅读 4,255评论 0 2
  • 花2天把Leetcode上Linked lists的题目刷完了,下面是一些我觉得比较有倾诉欲望的题。 237. D...
    __小赤佬__阅读 629评论 0 1
  • LeetCode 刷题随手记 - 第一部分 前 256 题(非会员),仅算法题,的吐槽 https://leetc...
    蕾娜漢默阅读 17,941评论 2 36
  • //leetcode中还有花样链表题,这里几个例子,冰山一角 求单链表中结点的个数----时间复杂度O(n)这是最...
    暗黑破坏球嘿哈阅读 1,540评论 0 6
  • 链表问题是面试过程中经常被问到的一部分,很考查编程功底。最近刷了 LeetCode 上链表部分的面试题,我总结了一...
    JohnnyShieh阅读 4,984评论 0 9