您的位置:首页 > 编程语言 > Java开发

LeetCode OJ平台上Linked List Cycle题目用java快慢遍历实现

2014-06-07 15:44 363 查看
原始题目如下,意为判断某单向链表是否存在环。

Given a linked list, determine if it has a cycle in it.

Follow up:

Can you solve it without using extra space?

链表节点结构如下

class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}


关于这道题目,有很多很有意思的讨论。

solution 1 : 设置一个辅助变量flag,值为java里面int型的最大值,2^31-1。遍历过程中,如果节点值不等于flag,则置当前节点值为flag。如果相等,则说明链表有环。

问题是,这个思路很不完善。如果测试用例里的无循环链接某节点值恰巧就是int最大值,则必挂无疑。

solution 2:遍历链表,如果某节点.next == null,说明链接无循环。

问题是,如果链表真的有循环,则这个遍历永远不会终止。

呵呵,最后在论坛各位前辈的帖子指导下,用快慢两个节点来实现,有点像C的指针,两个节点初始化为head节点,快节点每次走两步,慢节点每次走一步。如果两个节点中途变为null则说明链表无循环,如果两个节点中途变成相等的,说明肯定存在循环。

可能会有人担心,快节点每次走两步,会不会恰巧跳过了链表循环节点,答案是不会,因为最小的循环是两个节点,快节点走两步绝对不会跳过。

可能还有人会担心,快慢节点真的会在循环里面相遇么?答案是肯定的。任何一个循环,二者循环一定次数后必定会相遇。自己动手画画奇偶数个节点,快慢节点肯定会相遇的。

public class Solution {
public static boolean hasCycle(ListNode head) {
ListNode faster = head;
ListNode slower = head;
boolean s = false;
while(faster != null && slower != null){
slower = slower.next;
faster = faster.next;
if(faster == null || faster.next == null)
break;
else
faster = faster.next;
if(faster.equals(slower)){
s = true;
break;
}
}
return s;
}
public static void main(String args[]){
ListNode head = new ListNode(1);
ListNode h2 = new ListNode(2);
ListNode h3 = new ListNode(3);
ListNode h4 = new ListNode(4);
head.next = h2;
h2.next = null;// h3;
h3.next = h4;
h4.next = head;
System.out.println(hasCycle(head));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: