• PHP 判断链表是否相交


    解题思路:

    分三种情况

    1.两个链表都是无环链表,则使用指针p1,p2,分别遍历到两个链表尾,如果p1===p2,说明链表相交,否则不相交

    2.两个链表有一个有环,另一个无环,那么这种情况链表肯定不相交,因为如果其中一个有环,另一个和它相交,另一个也肯定会有环

    3.两个链表都有环,找到链表a和链表b的环中的两个节点p1,p2,用pa=p1,然后用pa=pa->next,直到pa===p1(意思是让pa在环内跑一圈),如果在跑的过程中发现pa === p2,说明两个链表的环是同一个,则相交,如果到达pa===p1,说明两个链表不相交

    下面是代码

      1 <?php
      2     #判断链表是否相交
      3     #一共有三种情况
      4     #1.两个链表都是无环链表
      5     #2.一个是有环链表,另一个是无环链表,这种情况不可能相交
      6     #3.两个链表都是有环链表
      7 
      8     class Node {
      9         public $data;
     10         public $next;
     11     }
     12 
     13     #判断是否有环
     14     function test_circle($head) {
     15         $p1 = $head;
     16         $p2 = $head;
     17 
     18         while ($p2 != null && $p2->next != null) {
     19             $p1 = $p1->next;
     20             $p2 = $p2->next->next;
     21 
     22             #链表存在环,注意要用===
     23             if ($p1 === $p2) {
     24                 return $p1;
     25             }
     26         }
     27 
     28         #链表无环
     29         return null;
     30     }
     31 
     32     #判断两个无环链表是否相交
     33     function test_intersect_simple($head1, $head2) {
     34         $p1 = $head1;
     35         $p2 = $head2;
     36 
     37         while ($p1->next != null) {
     38             $p1 = $p1->next;
     39         }
     40 
     41         while ($p2->next != null) {
     42             $p2 = $p2->next;
     43         }
     44 
     45         #如果两个链表相交,则他们末必然相等
     46         #此处要注意用三等号,因为要判断引用是否相同
     47         return $p1 === $p2 ? true : false;
     48     }
     49 
     50     #判断两个链表是否相交
     51     function test_intersect($head1, $head2) {
     52         $cir1 = test_circle($head1);
     53         $cir2 = test_circle($head2);
     54 
     55         #两个链表都无环
     56         if ($cir1 == null && $cir2 == null) {
     57             return test_intersect_simple($head1, $head2);
     58         }
     59 
     60         #如果其中一个链表存在环另一个不存在环,则肯定不会相交
     61         if (($cir1 != null && $cir2 == null) || ($cir1 == null && $cir2 != null)) {
     62             return false;
     63         }
     64 
     65         #两个链表都存在环,如果相交,则两个链表的环肯定是同一个
     66         #利用cir1在环内走一圈,如果没有遇到cir2,说明两个链表不相交
     67         $p = $cir1;
     68         while ($cir1 !== $cir2) {
     69             $cir1 = $cir1->next;
     70             if ($p === $cir1) {
     71                 return false;
     72             }
     73         }
     74         return true;
     75     }
     76 
     77     #head1,head2无环且相交
     78     $head1 = new Node();
     79     $head2 = new Node();
     80     $n11 = new Node();
     81     $n12 = new Node();
     82     $n21 = new Node();
     83     $n22 = new Node();
     84     $n23 = new Node();
     85     $np1 = new Node();
     86     $np2 = new Node();
     87     $head1->next = $n11;
     88     $n11->next = $n12;
     89     $n12->next = $np1;
     90     $np1->next = $np2;
     91     $head2->next = $n21;
     92     $n21->next = $n22;
     93     $n22->next = $n23;
     94     $n23->next = $np1;
     95 
     96     $t = test_intersect($head1, $head2);
     97     var_dump($t);
     98     echo "<br>";
     99 
    100     #head1,head2其中一个有环
    101     $head1 = new Node();
    102     $head2 = new Node();
    103     $n11 = new Node();
    104     $n12 = new Node();
    105     $n21 = new Node();
    106     $n22 = new Node();
    107     $n23 = new Node();
    108     $head1->next = $n11;
    109     $n11->next = $n12;
    110     $n12->next = $head1;
    111     $head2->next = $n21;
    112     $n21->next = $n22;
    113     $n22->next = $n23;
    114 
    115     $t = test_intersect($head1, $head2);
    116     var_dump($t);
    117     echo "<br>";
    118 
    119     #head1,head2都有环且相交
    120     $head1 = new Node();
    121     $head2 = new Node();
    122     $n11 = new Node();
    123     $n12 = new Node();
    124     $n21 = new Node();
    125     $n22 = new Node();
    126     $n23 = new Node();
    127     $head1->next = $n11;
    128     $n11->next = $n12;
    129     $n12->next = $head1;
    130     $head2->next = $n21;
    131     $n21->next = $n22;
    132     $n22->next = $n23;
    133     $n23->next = $n12;
    134 
    135     $t = test_intersect($head1, $head2);
    136     var_dump($t);
    137     echo "<br>";
    138 ?>

    bool(true) 
    bool(false) 
    bool(true)

  • 相关阅读:
    Java自学
    Java自学
    Java自学
    java自学
    Java自学
    mybatis基础及原理
    自定义swagger maven codegen插件
    spring学习总结016 --- spring事务原理
    spring学习总结015 --- spring事务
    windows解决端口占用问题
  • 原文地址:https://www.cnblogs.com/zemliu/p/2707151.html
Copyright © 2020-2023  润新知