141、环形链表 142、环形链表II

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/benzhaohao/article/details/85483662

141、环形链表

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

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

解题思路:

定义一快一慢两个指针,如果链表有环,两个指针必定在某个地方相遇。

/**
 * 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 fast=head;
	    ListNode slow=head;
        //fast和fast.next不为空
	    while(fast!=null&&fast.next!=null) {  
	    	fast=fast.next.next;
            slow=slow.next;
	    	if(slow==fast)
	    		return true;
	    }
	    return false;
    }
}

142、环形链表II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。

说明:不允许修改给定的链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。

解题思路:

参考原文:https://blog.csdn.net/ds19980228/article/details/84096184

 如图所示 , 当fast与slow相遇时,slow还没走完链表,而fast已经在环内循环了n圈了,假设slow在相遇前走了s步,则fast走了2s步,设环长为r,有2s=s+nr,即s=nr.由上图可知a+x=s, x+y=r,而我们的目标是找到a的位置。设上图那个拱起的曲线的长度为y,有a+x=s=nr=(n-1)r+r=(n-1)r+y+x ,则a=(n-1)r+y . 这个公式告诉我们,在链表头和相遇点分别定义一个指针,每次各走一步,这两个指针必定相遇,且相遇的第一个点为环入口点 。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        //定义快指针,慢指针,头指针
		ListNode fast,slow,node;
		fast=slow=node=head;
        //第一步,判断链表是否有环
		while(fast!=null&&fast.next!=null) {
			fast=fast.next.next;
			slow=slow.next;
            //第二步,如果链表有环,node为环入口点
			if(fast==slow) {
				while(fast!=node) {
					fast=fast.next;
					node=node.next;
				}
				return node;
			}
		}
		return null;
    }
}

猜你喜欢

转载自blog.csdn.net/benzhaohao/article/details/85483662