leetcode-141-环形链表(linked list cycle)-java

题目及用例

package pid141;
/*环形链表

给定一个链表,判断链表中是否有环。

进阶:
你能否不使用额外空间解决此题?


*/


import pid141.LinkList;
import pid141.LinkList.ListNode;

public class main {
	
	
	public static void main(String[] args) {
		
		LinkList a=new LinkList(1);
		a.addLast(2);
		a.addLast(5);
		a.printList();
		test(a.first);
		
		LinkList b=new LinkList(-5);
		b.addLast(0);
		b.addLast(-5);
		b.first.next.next=b.first;
		//b.printList();
		test(b.first);		
		
		/*LinkList c=new LinkList(1);
		c.addLast(2);
		c.addLast(2);
		c.addLast(1);
		c.printList();
		test(c.first);*/
		
		/*LinkList c=new LinkList(1);
		c.addLast(2);
		c.addLast(500);
		LinkList d=new LinkList(1);
		d.addLast(2);
		d.addLast(3);
		
		c.printList();		
		d.printList();
		test(c.first,d.first);*/
	}
		 
	private static void test(ListNode ito) {
		Solution solution = new Solution();
		Boolean rtn;
		long begin = System.currentTimeMillis();
		System.out.println();
		//开始时打印数组
		
		rtn=solution.hasCycle(ito);//执行程序
		long end = System.currentTimeMillis();	
		
		System.out.println(rtn);
		
		//System.out.println(":rtn" );
		//System.out.print(rtn);
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,速度极快,1ms)
不用额外空间,速度o(n)
用双指针,一个在前,另一个在第一个的后面一步
每走一步,将这一步后面的next改为head
这样如果走到的next=head,说明循环
如果为null,不循环

package pid141;


import java.util.ArrayList;
import java.util.List;

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

解法2(成功,1ms,极快)
也不错,用双指针,快慢指针,一个一步2格,1个1格
如果循环,那么一定会相遇

    public boolean hasCycle(ListNode head) {
    	if(head==null||head.next==null){
    		return false;
    	}
        ListNode slow=head.next;
        ListNode fast=head.next.next;
        while(fast!=null&&fast.next!=null){
        	if(slow==fast){
        		return true;
        	}
        	else{
        		slow=slow.next;
        		fast=fast.next.next;
        	}
        }
    	return false;
    }

解法3(别人的)
与第一种相似,只是将指针指向head改为指向自己


public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null||head.next==null)return false;
        if(head.next==head)return true;
        ListNode l=head.next;
        head.next=head;
        boolean isCycle=hasCycle(l);
        return isCycle;
    }

你可能感兴趣的:(数据结构-双指针,数据结构-链表,leetcode-初级,leetcode)