两个单链表相交的问题

单链表可能有环无环;

给定两个 单链表的头节点 head1和head2,这两个链表可能相交,也可能 不相交。请实现一个函数, 如果两个链表相交,请返回相交的 第一个节点;如果不相交,返回null 即可。

链表长度分别为 N M, 时间复杂度O(N + M);额外空间 O(1) ;

  1 package my_basic.class_3;
  2 
  3 public class FindFirstIntersectNode {
  4     public static class Node{
  5         int value;
  6         Node next;
  7         public Node(int data) {
  8             this.value = data;
  9         }
 10     }
 11     /**
 12      * 找到相交节点
 13      * @return
 14      */
 15     public static Node getIntersectNode(Node head1,Node head2) {
 16         if (head1 == null || head2==null) {
 17             return null;
 18         }
 19         //环节点
 20         Node loop1 = getLoopNode(head1);
 21         Node loop2 = getLoopNode(head2);
 22         
 23         if (loop1 == null && loop2 == null) {
 24             return getNoLoop(head1,head2);
 25         }
 26         if (loop1!=null && loop2!=null) {
 27             return bothLoop(head1,loop1,head2,loop2);
 28         }
 29         return null;
 30         
 31     }
 32     
 33     //判断有没有环 如果有环 返回第一个入环节点
 34     //第1种:hashset实现 
 35     //第2种:一个快指针 一个慢指针 ; 如果相遇了, 快指针从头开始 每次一步走,首次相遇的节点就是第一个入环节点
 36     public static Node getLoopNode(Node head) {
 37         //2. 
 38         if (head == null || head.next == null || head.next.next == null ) {
 39             return null;
 40         }
 41         Node n1;  //slow
 42         Node n2;  //fast
 43         n1 = head.next;
 44         n2 = head.next.next;
 45         while(n1 != n2) {
 46             if (n2.next == null || n2.next.next == null ) {
 47                 return null;
 48             }
 49             n1 = n1.next;
 50             n2 = n2.next.next;
 51         }
 52         n2 = head;
 53         while (n1 != n2) {
 54             n1 = n1.next;
 55             n2 = n2.next;
 56         }
 57         return n1;
 58         
 59         //1. 需要额外的哈希表做辅助空间
 60         /*HashSet<Object> set = new HashSet<>();
 61         Node n1 = head;  
 62         while (n1 != null) {
 63             if (set.contains(n1)) {
 64                 return n1;
 65             }
 66             set.add(n1);
 67             n1 = n1.next;
 68         }
 69         return null;*/
 70     }
 71     
 72     //都没有环: 也可以借助hashset
 73     public static Node getNoLoop(Node head1, Node head2) {
 74         if (head1==null || head2 == null) {
 75             return null;
 76         }
 77         Node cur1 = head1;  //long list
 78         Node cur2 = head2;  //short  list
 79         int n=0;
 80         while (cur1.next != null) {
 81             n++;
 82             cur1 = cur1.next;
 83         }
 84         while (cur2.next != null) {
 85             n--;
 86             cur2 = cur2.next;
 87         }
 88         if (cur1 != cur2) {
 89             return null;
 90         } 
 91         cur1 = n>0 ? head1 : head2;
 92         cur2 = cur1 == head1 ? head2 : head1;
 93         
 94         n = Math.abs(n);
 95         while (n != 0) {
 96             n--;
 97             cur1 = cur1.next;
 98         }
 99         while (cur1 != cur2) {
100             cur1 = cur1.next;
101             cur2 = cur2.next;
102         }
103         return cur1;
104     }
105     
106     //都有环: 也可以借助hashset
107     public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
108         if (loop1 == loop2 ) {
109             Node cur1 = head1;  //long
110             Node cur2 = head2;  //short
111             int n=0;
112             while (cur1.next != loop1) {
113                 n++;
114                 cur1 = cur1.next;
115             }
116             while (cur2.next != loop2) {
117                 n--;
118                 cur2 = cur2.next;
119             }
120             if (cur1 != cur2) {
121                 return null;
122             } 
123             cur1 = n>0 ? head1 : head2;
124             cur2 = cur1 == head1 ? head2 : head1;
125             
126             n = Math.abs(n);
127             while (n > 0) {
128                 n--;
129                 cur1 = cur1.next;
130             }
131             while (cur1 != cur2) {
132                 cur1 = cur1.next;
133                 cur2 = cur2.next;
134             }
135             return cur1;
136         }else{
137             Node n = loop1.next;
138             while(n != loop1) {
139                 if (n == loop2) {
140                     return loop1;
141                 }
142                 n = n.next;
143             }
144             return null;
145         }
146     }
147     
148     public static void main(String[] args) {
149         // 1->2->3->4->5->6->7->null
150         Node head1 = new Node(1);
151 //        head1.next = new Node(2);
152 //        head1.next.next = new Node(3);
153 //        head1.next.next.next = new Node(4);
154 //        head1.next.next.next.next = new Node(5);
155 //        head1.next.next.next.next.next = new Node(6);
156 //        head1.next.next.next.next.next.next = new Node(7);
157 //
158 //        // 0->9->8->6->7->null
159         Node head2 = new Node(0);
160 //        head2.next = new Node(9);
161 //        head2.next.next = new Node(8);
162 //        head2.next.next.next = head1.next.next.next.next.next; // 8->6
163 //        System.out.println(getIntersectNode(head1, head2).value);
164 //
165         // 1->2->3->4->5->6->7->4...
166         head1 = new Node(1);
167         head1.next = new Node(2);
168         head1.next.next = new Node(3);
169         head1.next.next.next = new Node(4);
170         head1.next.next.next.next = new Node(5);
171         head1.next.next.next.next.next = new Node(6);
172         head1.next.next.next.next.next.next = new Node(7);
173         head1.next.next.next.next.next.next.next = head1.next.next.next; // 7->4
174 
175 //        // 0->9->8->2...
176 //        head2 = new Node(0);
177 //        head2.next = new Node(9);
178 //        head2.next.next = new Node(8);
179 //        head2.next.next.next = head1.next; // 8->2
180 //        System.out.println(getIntersectNode(head1, head2).value);
181 
182         // 0->9->8->6->4->5->6..
183         head2 = new Node(0);
184         head2.next = new Node(9);
185         head2.next.next = new Node(8);
186         head2.next.next.next = head1.next.next.next.next.next; // 8->6
187         System.out.println(getIntersectNode(head1, head2).value);
188 
189     }
190 }

猜你喜欢

转载自www.cnblogs.com/lihuazhu/p/10782583.html