layout: posttitle: PHP 和 Go 环路链表检测
subtitle: PHP 和 Go 环路链表检测
date: 2020-10-09
author: he xiaodong
header-img: img/default-post-bg.jpg
catalog: true
tags:
- Go
- PHP
- LeetCode 141
- 环形链表

环路链表检测

给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。
有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle-lcci

解题思路 1

遍历链表,同时将每次的结果放到 map 中,如果有元素重复出现,则是有环形链表

代码
  1. /**
  2. * Definition for singly-linked list.
  3. * type ListNode struct {
  4. * Val int
  5. * Next *ListNode
  6. * }
  7. */
  8. func detectCycle(head *ListNode) *ListNode {
  9. visited := make(map[*ListNode]struct{}, 1)
  10. work := head
  11. for work != nil {
  12. _, ok := visited[work]
  13. if ok {
  14. return work
  15. } else {
  16. visited[work] = struct{}{}
  17. }
  18. work = work.Next
  19. }
  20. return nil
  21. }

解题思路 2

快慢指针求解:我们定义两个指针,一快一满。慢指针每次只移动一步,而快指针每次移动两步。初始时,慢指针在位置 head,而快指针在位置 head.next。这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表。否则快指针将到达链表尾部,该链表不为环形链表。

  1. /**
  2. * Definition for a singly-linked list.
  3. * class ListNode {
  4. * public $val = 0;
  5. * public $next = null;
  6. * function __construct($val) { $this->val = $val; }
  7. * }
  8. */
  9. class Solution {
  10. /**
  11. * @param ListNode $head
  12. * @return Boolean
  13. */
  14. function hasCycle($head) {
  15. $fast = $head;
  16. $slow = $head;
  17. while ($fast != null && $fast->next != null) {
  18. $fast = $fast->next->next;
  19. $slow = $slow->next;
  20. if ($fast === $slow) {
  21. return true;
  22. }
  23. }
  24. return false;
  25. }
  26. }

最后恰饭 阿里云全系列产品/短信包特惠购买 中小企业上云最佳选择 阿里云内部优惠券