解题思路:

分三种情况

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)

posted on 2012-09-28 14:34  ZimZz  阅读(522)  评论(0编辑  收藏  举报