解题思路:
分三种情况
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)