zoukankan      html  css  js  c++  java
  • 142.环形链表2——找开始的起点

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

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

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

    链接:https://leetcode-cn.com/problems/linked-list-cycle-ii
    自己的代码以及思路:

    1.先通过快慢指针找到相交的点。(这边快慢指针好像都是从头开始的,然后我的快指针是从head.next开始的,会差一位)

    2.然后其中一个指针从相交的点出发,头结点从头出发,两个点相交的点就是环中第一个相交的点。

    /**
     * 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) {
            if (head == null || head.next == null) {
                return null;
            }
            //step1 find meet
            ListNode slow = head;
            ListNode fast = head.next;
            ListNode meet= new ListNode(-999);
            ListNode head_copy= new ListNode(-999);
            head_copy=head;
    
            while (slow != fast) {
            if (fast == null || fast.next == null) {
                return null;
                }
            slow = slow.next;
            fast = fast.next.next;
            }
    
            System.out.println(slow.val);
            System.out.println(fast.val);
            
            meet=fast.next;
            // head_copy=head;
    
            while(meet!=head_copy)
            {   
                // System.out.println("meet"+meet.val);
                // System.out.println("head_copy"+head_copy.val);
                meet=meet.next;
                head_copy=head_copy.next;
            }
            return head_copy;
        }
    }

    Leetcode题解的方法:

    方法 1:哈希表
    想法

    如果我们用一个 Set 保存已经访问过的节点,我们可以遍历整个列表并返回第一个出现重复的节点。

    算法

    首先,我们分配一个 Set 去保存所有的列表节点。我们逐一遍历列表,检查当前节点是否出现过,如果节点已经出现过,那么一定形成了环且它是环的入口。否则如果有其他点是环的入口,我们应该先访问到其他节点而不是这个节点。其他情况,没有成环则直接返回 null 。

    算法会在遍历有限个节点后终止,这是因为输入列表会被分成两类:成环的和不成环的。一个不成环的列表在遍历完所有节点后会到达 null - 即链表的最后一个元素后停止。一个成环列表可以想象成是一个不成环列表将最后一个 null 元素换成环的入口。

    如果 while 循环终止,我们返回 null 因为我们已经将所有的节点遍历了一遍且没有遇到重复的节点,这种情况下,列表是不成环的。对于循环列表, while 循环永远不会停止,但在某个节点上, if 条件会被满足并导致函数的退出。

    public class Solution {
        public ListNode detectCycle(ListNode head) {
            Set<ListNode> visited = new HashSet<ListNode>();
    
            ListNode node = head;
            while (node != null) {
                if (visited.contains(node)) {
                    return node;
                }
                visited.add(node);
                node = node.next;
            }
    
            return null;
        }
    }

    方法2:和那个视频里讲的是一样的。

    public class Solution {
        private ListNode getIntersect(ListNode head) {
            ListNode tortoise = head;
            ListNode hare = head;
    
            // A fast pointer will either loop around a cycle and meet the slow
            // pointer or reach the `null` at the end of a non-cyclic list.
            while (hare != null && hare.next != null) {
                tortoise = tortoise.next;
                hare = hare.next.next;
                if (tortoise == hare) {
                    return tortoise;
                }
            }
    
            return null;
    }
    
        public ListNode detectCycle(ListNode head) {
            if (head == null) {
                return null;
            }
    
            // If there is a cycle, the fast/slow pointers will intersect at some
            // node. Otherwise, there is no cycle, so we cannot find an e***ance to
            // a cycle.
            ListNode intersect = getIntersect(head);
            if (intersect == null) {
                return null;
            }
    
            // To find the e***ance to the cycle, we have two pointers traverse at
            // the same speed -- one from the front of the list, and the other from
            // the point of intersection.
            ListNode ptr1 = head;
            ListNode ptr2 = intersect;
            while (ptr1 != ptr2) {
                ptr1 = ptr1.next;
                ptr2 = ptr2.next;
            }
    
            return ptr1;
        }
    }
  • 相关阅读:
    oracle执行完shutdown immediate后登陆不上了怎么办
    软件工程实践2017第一次作业-准备
    工作准备
    第二次作业——个人项目实战
    第一次作业-准备
    软件工程实践第二次作业-个人项目实战
    软件工程实践第一次作业-准备
    关于在git添加远程地址的过程中遇到的问题
    在配置github中遇到的一些问题
    软件工程实践第一次作业--准备
  • 原文地址:https://www.cnblogs.com/William-xh/p/13649804.html
Copyright © 2011-2022 走看看