leetcode-160- 相交链表(intersection of two linked list)-java

版权声明:此文章为许诗宇所写,如需转载,请写下转载文章的地址 https://blog.csdn.net/xushiyu1996818/article/details/84026020

题目及测试

package pid160;
/*   相交链表

编写一个程序,找到两个单链表相交的起始节点。

 

例如,下面的两个链表:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

在节点 c1 开始相交。

 

注意:

    如果两个链表没有交点,返回 null.
    在返回结果后,两个链表仍须保持原有的结构。
    可假定整个链表结构中没有循环。
    程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

 

致谢:
特别感谢 @stellari 添加此问题并创建所有测试用例。



*/
public class main {
	
public static void main(String[] args) {
		ListNode c=new ListNode(0);
		c.next=new ListNode(-1);
		
		LinkList a=new LinkList(1);
		a.addLast(2);
		a.addLast(3);
		a.first.next.next.next=c;
		a.printList();
		//test(a.first);
		
		LinkList b=new LinkList(5);
		b.addLast(6);
		b.addLast(4);
		b.addLast(2);
		b.first.next.next.next.next=c;
		b.printList();
		test(a.first,b.first);		
		/*
		LinkList c=new LinkList(1);
		c.addLast(2);
		c.addLast(2);
		c.addLast(1);
		c.printList();
		//test(c.first);
		
		
		LinkList d=new LinkList(1);
		d.addLast(2);
		d.addLast(3);
		
		c.printList();		
		d.printList();
		test(c.first,d.first);*/
	}
		 
	private static void test(ListNode ito,ListNode ito2) {
		Solution solution = new Solution();
		ListNode rtn;
		long begin = System.currentTimeMillis();
		System.out.println();
		//开始时打印数组
		
		rtn=solution.getIntersectionNode(ito,ito2);//执行程序
		long end = System.currentTimeMillis();	
		System.out.println("rtn=");
		rtn.printNodeToEnd();
		
		//System.out.println(":rtn" );
		//System.out.print(rtn);
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,2ms,超快)

首先有一点非常重要,相交节点后的所有节点 (包括相交节点) 都是两个链表共享的。

我们将两个链表的右端对齐,长度较大的链表 的左端的 多出来的节点 肯定不是相交节点,所以我们不考虑左端的这一部分的节点

使用双指针算法,先遍历一遍两个链表的长度,再将两个指针指向两个链表头部,移动长的链表的指针,指向相同距离的位置,再两个指针一起走,如果指针相遇,则得到相同节点

package pid160;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    if(headA==null||headB==null){
    	return null;
    }
    int lengthA=0;
    int lengthB=0;
    ListNode now=headA;
    while(now!=null){
    	lengthA++;
    	now=now.next;
    }
    now=headB;
    while(now!=null){
    	lengthB++;
    	now=now.next;
    }
    ListNode nowA=headA;
    ListNode nowB=headB;
    if(lengthA>lengthB){
    	for(int i=0;i<lengthA-lengthB;i++){
    		nowA=nowA.next;
    	}
    }
    if(lengthA<lengthB){
    	for(int i=0;i<lengthB-lengthA;i++){
    		nowB=nowB.next;
    	}
    }
    ListNode result=null;
    while(true){
    	if(nowA==nowB){
    		result=nowA;
    		break;
    	}
    	if(nowA==null||nowB==null){
    		break;
    	}
    	nowA=nowA.next;
    	nowB=nowB.next;    	
    }   	
	return result;
    }
}

网上还有两种解法,都不太好

有以下几种思路:
(1)暴力破解,遍历链表A的所有节点,并且对于每个节点,都与链表B中的所有节点比较,退出条件是在B中找到第一个相等的节点。时间复杂度O(lengthA*lengthB),空间复杂度O(1)。

(2)哈希表。遍历链表A,并且将节点存储到哈希表中。接着遍历链表B,对于B中的每个节点,查找哈希表,如果在哈希表中找到了,说明是交集开始的那个节点。时间复杂度O(lengthA+lengthB),空间复杂度O(lengthA)或O(lengthB)。
 

猜你喜欢

转载自blog.csdn.net/xushiyu1996818/article/details/84026020