zoukankan      html  css  js  c++  java
  • [LeetCode]142. 环形链表 II

    题目

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

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

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

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/linked-list-cycle-ii
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    题解

    • step1 使用快慢指针判断有无环。使每次快指针走2步,慢指针走1步。
      • PS 两指针并不一定在慢指针走环形第一圈就相遇。当非环形部分很长,环形一圈很短的情况易见。
      • 若快指针每次走三步,若慢指针进入环形后,两支针相差奇数圈,但每次快追慢距离为2,则永远不可能追上。(待验证结论正确性?)
    • step2 画图理解。
      • 设链表起点到环形起点的距离为x,环形起点到快慢指针相遇点距离为y,环形的长度为c。由同一时刻快指针是慢指针走的距离2倍,有2*(x+n1*c+y)=x+n2*c+y
      • <=> x+y=(n2-n1)*c ,理解式子含义为从环中任意一点走x+y步,还能回到这点
      • =>(从起始点走了y步的)在相遇点的指针再走x步,还能回到环形起始点
      • 故让在相遇点的慢指针再走x步即可找到环形入口

    代码

    /**
     * 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) {
    		// 判断有无环
    		ListNode fast = head;
    		ListNode slow = head;
    		boolean hasCycleFlag = false;
    		while (fast != null && fast.next != null) {//
    			fast = fast.next.next;
    			slow = slow.next;
    			if (fast == slow) {
    				hasCycleFlag = true;
    				break;
    			}
    		}
    
    		// 若无环直接返回null,否则找到环的起点并返回
    		if (!hasCycleFlag) {
    			return null;
    		} else {
    			ListNode p = head;
    			while (p != slow) {
    				p = p.next;
    				slow = slow.next;
    			}
    			return p;
    		}
    	}
    }
    
  • 相关阅读:
    第5章 构建Spring Web应用程序
    第4章 面向切面的Spring
    第3章 高级装配
    js json和字符串的互转
    webservice CXF入门服务端
    javascript的解析执行顺序
    java AES加密解密
    redis学习 java redis应用
    项目部署操作linux数据库mysql出现表找不到
    灯具板SOP
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/11780360.html
Copyright © 2011-2022 走看看