两个单链表相交的一系列问题

来源:互联网 发布:java垃圾回收机制 英文 编辑:程序博客网 时间:2024/06/05 14:49
两个单链表相交的一系列问题
在本题中,单链表可能有环,也可能无环。给定两个单链表的头节点 head1 和 head2,这两个链表可能相交,也可能
不相交。请实现一个函数,如果两个链表相交,请返回相交的第一个节点;如果不相交,返回 null 即可。
如果链表 1 的长度为 N,链表 2 的长度为 M,时间复杂度请达到 O(N+M),额外空间复杂度请达到 O(1)。(界定啊相交是内存地址相同)


方法:哈希表(极简单适用一切情况)依次遍历,每遍历一个节点,将其加入哈希表中,若遍历到链表最后一个节点也没有发现哈希表中有之前已经记录的节点,则表示链表无环,若遍历到某个节点发现哈希表中已经存过这个节点,则表示有环,且这个节点是第一个相交的节点。另一种方法,建立两个指针,一个快指针,一个慢指针,慢指针依次遍历链表中每个节点,快指针跳步前进,每次走两个节点,则这两个指针一定会在环中相遇,当两个指针相遇时,在链表开头再设置一个指针,开头的指针跟慢指针都继续移动,每次一步,则两个指针一定能在第一个环节点相遇


一个有环,一个无环,不可能相交
两个无环链表,可以相交,有两种结构(“||”和“Y”,不可能是“X”)不用哈希表的方法:分别得到两个链表的长度,若一个长度为50,一个长度为40,则较长的链表的指针先走10个节点,之后两个链表的指针同步前进,若出现某时刻两个指针相等,则表示相交,即“Y”,否则两链表结构是“||”
两个链表都有环:
两个链表各自都有环,没有相交,即“66”结构
两个链表在环外相交,即
Y
O
若两个链表的入环节点是同一个,则表示是“YO”结构,则求第一个相交节点与“Y”情况解法相同
两个链表共享环,即
||
O

两个链表的指针,从头开始,若Node1走到自身的节点也没有遇到Node2,则表示两个链表无交点,是“66”结构,若两个链表的指针在遇到自身节点之前遇到了另一个链表的节点,则表示“||O”结构

public static class Node{public int value;public Node next;public Node(int data){this.value = data;}}public static Node getIntersectNode(Node haed1,Node head2){if(head1 == null || head2 == null){return null;}Node loop1 = getLoopNode(head1);Node loop2 = getLoopNode(head2);if(loop1 == null && loop2 == null){return noLoop(head1, head2);}if(loop1 != null && loop2 != null){return bothLoop(head1, loop1, head2, loop2);}return null;}public static Node getLoopNode(Node head){if(head == null || head.next == null || head.next.next == null){return null;}Node n1 = head.next;  //n1为慢指针Node n2 = head.next.next;//n2为快指针while(n1 != n2){if(n2.next == null || n2.next.next == null){return null;}n2 = n2.next.next;n1 = n1.next;}n2 = head;while(n1 != n2){n1 = n1.next;n2 = n2.next;}n2 = head;  //n2 从头重新开始走,且变为慢指针while(n1 != n2){n1 = n1.next;n2 = n2.next;}return n1;}public static Node noLoop(Node head1, Node head2){if(head1 == null || head2 == null){return null;}Node cur1 = head1;Node cur2 = head2;int n = 0;while(cur1.next != null){n++;cur1 = cur1.next;}while(cur2.next != null){n--;cur2 = cur2.next;}if(cur1 != cur2){return null;}cur1 = n > 0 ? head1 : head2;cur2 = cur1 == head1 ? head2 : head1;n = Math.abs(n);while(n != 0){n--;cur1 = cur1.next;}while(cur1 != cur2){cur1 = cur1.next;cur2 = cur2.next;}return cur1;}public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2){Node cur1 = null;Node cur2 = null;if(loop1 == loop2){cur1 = head1;cur2 = head2;int n = 0;while(cur1 != loop1){n++;cur1 = cur1.next;}while(cur2 != loop2){n--;cur2 = cur2.next;}return cur1;}else{cur1 = loop1.next;while(cur1 != loop1){if(cur1 == loop2){return loop1;}cur1 = cur1.next;}return null;}}


原创粉丝点击