leetcode题目
linked-list-cycle-ii
题目描述
* Given a linked list, return the node where the cycle begins.
* If there is no cycle, return null.
* Follow up:
* Can you solve it without using extra space?
思路
* 1、找到链表中的环中的一个节点(快慢指针相遇处)
* 2、一个指针从相遇处出发,一个指针从链表头节点出发,相遇处即为链表中环的起始点
(也可利用环中节点遍历一圈,确定环的长度N,然后利用两个指针一个先走N步,之后另一指针再走,
相遇节点即为环的起始点)
代码
package com.leetcode.list;
/**
* 题目:
* linked-list-cycle-ii
*
* 题目描述:
* Given a linked list, return the node where the cycle begins.
* If there is no cycle, return null.
* Follow up:
* Can you solve it without using extra space?
*/
public class ListCircleBegin {
static class ListNode{
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
/**
* 思路:
* 1、找到链表中的环中的一个节点(快慢指针相遇处)
* 2、一个指针从相遇处出发,一个指针从链表头节点出发,相遇处即为链表中环的起始点
*
* @param head 头节点
*/
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) {
return null;
}
// 找到环中的一个节点
ListNode nodeInCycle = findOneNodeInCircle(head);
if (nodeInCycle == null) {
return null;
}
// 两个指针,一个指向头节点,一个指向环中的这个节点
ListNode first = nodeInCycle;
ListNode second = head;
while (first != null && second != null) {
// 两指针相遇,找到环的起始节点
if (first == second) {
return first;
}
first = first.next;
second = second.next;
}
return null;
}
private ListNode findOneNodeInCircle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
// 快慢指针相遇
if (fast == slow) {
return fast;
}
}
return null;
}
public static void main(String[] args) {
ListNode head = createTestLinkedList();
ListNode newHead = new ListNode(13);
newHead.next = head;
head.next.next = newHead;
ListNode begin = new ListCircleBegin().detectCycle(newHead);
System.out.println(begin.val);
}
private static ListNode createTestLinkedList() {
ListNode head = new ListNode(0);
ListNode curNode = head;
for (int i = 1; i < 10; i++) {
curNode.next = new ListNode(i);
curNode = curNode.next;
}
return head;
}
}