• leetcode — linked-list-cycle-ii


    /**
     * Source : https://oj.leetcode.com/problems/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 LinkedListCycle2 {
    
        /**
         * 如果链表是循环的,则找到循环的开始节点
         * 否则,返回null
         *
         * 依然使用双指针法,如果是循环链表的话,
         * slow和fast第一次相遇之后,将slow = head,
         * 然后将slow和fast每次移动一个节点,第二次相遇的时候就是循环的起始节点
         *
         * 原理:
         * 假设head到start的距离a,slow和fast第一次相遇的位置距离start为b,循环链表周长为c,第一次相遇的时候fast走过的长度一定是slow的两倍,在过程中遍历了循环链表n次
         * (a + b) * 2 = a + n * c + b
         * 那么a = n*c - b => a + b = n*c
         * 也就是说,现在让两个指针slow指向head,fast指向第一次相遇的位置,然后每次两个指针移动一个节点,直到下一次相遇,正好走过n个周长,即下一次相遇在start位置
         *
         * @param head
         * @return
         */
        public LinkedNode findCycleStart (LinkedNode head) {
            if (head == null) {
                return null;
            }
            LinkedNode slow = head;
            LinkedNode fast = head;
            while (fast.next != null && fast.next.next != null) {
                slow = slow.next;
                fast = fast.next.next;
                if (slow == fast) {
                    break;
                }
            }
            if (fast == slow) {
                // 链表存在循环
                slow = head;
                while (slow != fast) {
                    slow = slow.next;
                    fast = fast.next;
                }
                return slow;
            }
            return null;
        }
    
        private class LinkedNode {
            int value;
            LinkedNode next;
    
        }
    
        /**
         * 创建普通的链表
         * @param arr
         * @return
         */
        public LinkedNode createList (int[] arr) {
            if (arr.length == 0) {
                return null;
            }
            LinkedNode head = new LinkedNode();
            head.value = arr[0];
            LinkedNode pointer = head;
            for (int i = 1; i < arr.length; i++) {
                LinkedNode node = new LinkedNode();
                node.value = arr[i];
                pointer.next = node;
                pointer = pointer.next;
            }
            return head;
        }
    
        /**
         * 将链表变为循环链表,循环起始为第index个node
         * @param head
         * @param index
         */
        public void makeCycle (LinkedNode head, int index) {
            if (head == null) {
                return;
            }
            LinkedNode tail = head;
            int count = 1;
            while (tail.next != null) {
                tail = tail.next;
                count++;
            }
            LinkedNode p = head;
            if (index > count) {
                index = index % count;
            } else if (index < 0) {
                index = Math.abs(index);
            }
            while (p != null) {
                index--;
                if (index < 1) {
                    tail.next = p;
                    break;
                }
                p = p.next;
            }
    
        }
    
        public static void main(String[] args) {
            LinkedListCycle2 linkedListCycle = new LinkedListCycle2();
            LinkedNode list = linkedListCycle.createList(new int[]{1,2,3,4,5});
    
            System.out.println(linkedListCycle.findCycleStart(list) + " == null");
    
            linkedListCycle.makeCycle(list, 2);
            System.out.println(linkedListCycle.findCycleStart(list).value + " == 2");
        }
    }
    
  • 相关阅读:
    OpenCR 固件修复
    E-PUCK2机器人-固件更新
    E-puck2机器人系列教程-2.软件的安装与使用
    E-PUCK2机器人-硬件
    E-puck2机器人系列教程-固件修复升级
    GridView
    TimePicker 和TimePickerDiag
    android中实现简单的播放
    ListView的使用
    android的activity的跳转
  • 原文地址:https://www.cnblogs.com/sunshine-2015/p/7906577.html
Copyright © 2020-2023  润新知