有两个单向链表(链表长度分别为 m,n),这两个单向链表有可能在某个元素合并,如下图所示的这样,也可能不合并。现在给定两个链表的头指针,在不修改链表的情况下,如何快速地判断这两个链表是否合并?如果合并,找到合并的元素,也就是图中的 x 元素。
    请用(伪)代码描述算法,并给出时间复杂度和空间复杂度。
    作业-week8 - 图1

    1. public class FindIntersect {
    2. public static class Node {
    3. public int value;
    4. public Node next;
    5. public Node(int data) {
    6. this.value = data;
    7. }
    8. }
    9. /*判断是否相交,如果相交,得到第一个相交点*/
    10. public static Node getIntersectNode(Node head1, Node head2) {
    11. if (head1 == null || head2 == null) {
    12. return null;
    13. }
    14. Node loop1 = getLoopNode(head1);
    15. Node loop2 = getLoopNode(head2);
    16. if (loop1 == null && loop2 == null) {
    17. return noLoop(head1, head2);
    18. }
    19. if (loop1 != null && loop2 != null) {
    20. return bothLoop(head1, loop1, head2, loop2);
    21. }
    22. return null;
    23. }
    24. /*
    25. * 判断是否存在环,如果存在,则找出环的入口点。
    26. * 入口点找法:快慢指针,块指针走两步,满指针走一步,如果存在循环,则在慢指针走完环前,总会和快指针相遇。
    27. */
    28. public static Node getLoopNode(Node head) {
    29. if (head == null || head.next == null || head.next.next == null) {
    30. return null;
    31. }
    32. Node n1 = head.next; // n1 -> slow
    33. Node n2 = head.next.next; // n2 -> fast
    34. while (n1 != n2) {
    35. if (n2.next == null || n2.next.next == null) {
    36. return null;
    37. }
    38. n2 = n2.next.next;
    39. n1 = n1.next;
    40. }
    41. n2 = head; // n2 -> walk again from head
    42. while (n1 != n2) {
    43. n1 = n1.next;
    44. n2 = n2.next;
    45. }
    46. return n1;
    47. }
    48. /*无环时的判断方法*/
    49. public static Node noLoop(Node head1, Node head2) {
    50. if (head1 == null || head2 == null) {
    51. return null;
    52. }
    53. Node cur1 = head1;
    54. Node cur2 = head2;
    55. int n = 0;
    56. while (cur1.next != null) {
    57. n++;
    58. cur1 = cur1.next;
    59. }
    60. while (cur2.next != null) {
    61. n--;
    62. cur2 = cur2.next;
    63. }
    64. if (cur1 != cur2) {
    65. return null;
    66. }
    67. cur1 = n > 0 ? head1 : head2;
    68. cur2 = cur1 == head1 ? head2 : head1;
    69. n = Math.abs(n);
    70. while (n != 0) {
    71. n--;
    72. cur1 = cur1.next;
    73. }
    74. while (cur1 != cur2) {
    75. cur1 = cur1.next;
    76. cur2 = cur2.next;
    77. }
    78. return cur1;
    79. }
    80. /*有环时的判断方法*/
    81. public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
    82. Node cur1 = null;
    83. Node cur2 = null;
    84. if (loop1 == loop2) {
    85. cur1 = head1;
    86. cur2 = head2;
    87. int n = 0;
    88. while (cur1 != loop1) {
    89. n++;
    90. cur1 = cur1.next;
    91. }
    92. while (cur2 != loop2) {
    93. n--;
    94. cur2 = cur2.next;
    95. }
    96. cur1 = n > 0 ? head1 : head2;
    97. cur2 = cur1 == head1 ? head2 : head1;
    98. n = Math.abs(n);
    99. while (n != 0) {
    100. n--;
    101. cur1 = cur1.next;
    102. }
    103. while (cur1 != cur2) {
    104. cur1 = cur1.next;
    105. cur2 = cur2.next;
    106. }
    107. return cur1;
    108. } else {
    109. cur1 = loop1.next;
    110. while (cur1 != loop1) {
    111. if (cur1 == loop2) {
    112. return loop1;
    113. }
    114. cur1 = cur1.next;
    115. }
    116. return null;
    117. }
    118. }
    119. public static void main(String args[]){
    120. //侧重算法,没有实现链表部分
    121. Node node1 = new Node(1);
    122. Node node2 = new Node(2);
    123. Node node3 = new Node(3);
    124. Node node4 = new Node(4);
    125. Node node5 = new Node(5);
    126. Node node6 = new Node(6);
    127. Node node7 = new Node(7);
    128. node1.next = node2;
    129. node2.next = node3;
    130. node3.next = node4;
    131. node4.next = node5;
    132. node5.next = node6;
    133. node6.next = node7;
    134. node7.next = node4;
    135. Node node11 = new Node(0);
    136. Node node22 = new Node(9);
    137. Node node33 = new Node(8);
    138. node11.next = node22;
    139. node22.next = node33;
    140. node33.next = node6;
    141. Node result = getIntersectNode(node1,node11);
    142. System.out.print(result.value); // 结果为4
    143. }
    144. }