LeetCode如何找出链表中环的入口节点

这篇文章主要介绍LeetCode如何找出链表中环的入口节点,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

题目

若一个链表中包含环,如何找出的入口结点?如下图链表中,环的入口节点的节点3。

LeetCode如何找出链表中环的入口节点

分析

  1. 一快(移两节点)一慢(移一节点)两指针判断链表是否存在环。

  2. 算出环有几个节点(上一步的两指针可知是在环中,让慢指针停止遍历,让快指针改为一节点一节点然后两指针一动一静的计算出环有多少个节点)。

  3. 重置两指针指向链头,一指针移动2. 步骤得出n,然后两指针一起移动。当两指针相遇,此时它们指向的环的入口结点

放码

import com.lun.util.SinglyLinkedList.ListNode;

public class FindEntryNodeOfLoop {

	public ListNode find(ListNode head) {
		
		//1.判断是否存在环
		ListNode meetNode = meetNode(head);
		
		if(meetNode == null) {
			return null;
		}
		
		int nodesInLoop = 1;
		
		ListNode node1 = meetNode;
		
		//2.计算环内节点
		while(node1.next != meetNode) {
			nodesInLoop++;
			node1 = node1.next;
		}
		
		//3.先移动node1, 次数为环中节点的数目
		node1 = head;
		for(int i = 0; i < nodesInLoop; i++)
			node1 = node1.next;
		
		ListNode node2 = head;
		while(node1 != node2) {
			node1 = node1.next;
			node2 = node2.next;
		}
		
		return node1;
	}

	
	public ListNode meetNode(ListNode head) {
		
		if(head == null)
			return null;
		
		ListNode slow = head.next;
		
		if(slow == null) {//链表只有一个节点
			return null;
		}
			
		ListNode fast = slow.next;
		
		while(fast != null && slow != null) {//可能循环几次才能碰上
		
			if(fast == slow) {
				return fast;
			}
			
			slow = slow.next;
			fast = fast.next;
			
			if(fast != null) {
				fast = fast.next;
			}
		}
		
		return null;
	}
	
}

测试

import static org.junit.Assert.*;

import org.junit.Test;

import com.lun.util.SinglyLinkedList;
import com.lun.util.SinglyLinkedList.ListNode;

public class FindEntryNodeOfLoopTest {

	@Test
	public void test() {	
		FindEntryNodeOfLoop fl = new FindEntryNodeOfLoop();
		
		ListNode n1 = new ListNode(1);
		ListNode n2 = new ListNode(2);
		ListNode n3 = new ListNode(3);
		ListNode n4 = new ListNode(4);
		ListNode n5 = new ListNode(5);
		ListNode n6 = new ListNode(6);
		
		n1.next = n2;
		n2.next = n3;
		n3.next = n4;
		n4.next = n5;
		n5.next = n6;
		
		n6.next = n3;//n3为入口节点
		
		assertEquals(3, fl.find(n1).val);
		
		//没有环的链表
		assertNull(fl.find(SinglyLinkedList.intArray2List(new int[] {1, 2, 3, 4, 5, 6})));
		
	}
	
	@Test
	public void test2() {
		FindEntryNodeOfLoop fl = new FindEntryNodeOfLoop();		
		assertNull(fl.meetNode(SinglyLinkedList.intArray2List(new int[] {1, 2, 3, 4, 5, 6})));
	}
	
}

以上是“LeetCode如何找出链表中环的入口节点”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

原创文章,作者:bd101bd101,如若转载,请注明出处:https://blog.ytso.com/tech/opensource/223573.html

(0)
上一篇 2022年1月7日 00:43
下一篇 2022年1月7日 00:43

相关推荐

发表回复

登录后才能评论