cci-Q2.5 寻找环形链表的起点

原文:

Given a circular linked list, implement an algorithm which returns node at the beginning of the loop.

DEFINITION

Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linked list.

EXAMPLE

Input: A –> B –> C –> D –> E –> C [the same C as earlier]

Output: C

译文:

给定一个循环链表,实现一个算法返回这个环的开始结点。

定义:

循环链表:链表中一个结点的指针指向先前已经出现的结点,导致链表中出现环。

例子:

输入:A –> B –> C –> D –> E –> C [结点C在之前已经出现过]

输出:结点C

两个指针移动,fast是slow的两倍,如果存在环形,一定有相遇。例如两辆汽车,如果存在环形,快的一定会超慢的车。

如果在一个环形中,fast是slow的两倍,那么相遇时,fast一定比slow多走一圈。

假设在环形中距start的x步相遇,链表环形外有k个节点,环形中有n个节点,那么2(k+x)=k+n+x => x=n-k,所以相遇的位置距离start有k步。

代码部分,首先寻找相遇点,然后确保链表中存在环形,之后再将slow移到head处,slow和fast都按照一次1步移动,两者相遇即是start

public static LinkedListNode findStart(LinkedListNode head) {
        LinkedListNode slow = head;
        LinkedListNode fast = head;

        while (fast != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                break;
            }
        }

        if (fast.next == null) {
            return null;
        }

        slow = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return fast;
    }

testcase:


public static void main(String args[]) {
        LinkedListNode head = new LinkedListNode(0);
        LinkedListNode node1 = new LinkedListNode(1);
        LinkedListNode cyclestart = new LinkedListNode(2);
        LinkedListNode node3 = new LinkedListNode(3);
        LinkedListNode node4 = new LinkedListNode(4);
        LinkedListNode node5 = new LinkedListNode(5);
        LinkedListNode node6 = new LinkedListNode(6);
        LinkedListNode tail = new LinkedListNode(7);

        head.next = node1;
        node1.next = cyclestart;
        cyclestart.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = tail;
        tail.next = cyclestart;

        //output cyclestart, the data is 2.
        System.out.println(findStart(head).data);

    }




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值