判断一个链表中是否含有环

来源:互联网 发布:电气设备市场数据 编辑:程序博客网 时间:2024/05/29 11:48

题目要求:判断一个链表(linked list)中是否含有环路

方法一:floyd算法。形象称为龟兔赛跑算法。维持两个指针rabbit和turtle,turtle一次前进一步,rabbit一次前进两步,如果两个指针能够相遇,则说明含有环路

/** * Definition for singly-linked list. * class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */public class Solution {    public boolean hasCycle(ListNode head) {        ListNode rabbit = head;        ListNode turtle = head;                while(true){            if(rabbit == null)                return false;            rabbit = rabbit.next;            if(rabbit == null)                return false;            rabbit = rabbit.next;            turtle = turtle.next;            if(rabbit == turtle)                return true;        }    }}

方法二:Brent算法。是基于floyd算法思想的改进。仍然维持两个指针,turtle原地不动,rabbit一次前进一步,同时维护两个变量,step_taken表示rabbit已经走的步数,rabbit每走一步其值加一。step_limit表示rabbit所走步数的上限值,当step_taken值达到step_limit上限时,直接将turtle移到rabbit所在的位置,然后重复执行,如果turtle和rabbit相遇,表示有环。

public class Solution {    public boolean hasCycle(ListNode head) {        int step_taken = 0;        int step_limit = 2;        ListNode rabbit = head;        ListNode turtle = head;                while(true){            if(rabbit == null)                return false;            rabbit = rabbit.next;            step_taken++;            if(rabbit == turtle)                return true;            if(step_taken == step_limit){                turtle = rabbit;                step_limit *= 2;                step_taken = 0;            }        }    }}


0 0