题目:
一个比較经典的问题,推断两个链表是否相交。假设相交找出他们的交点。
首先来看一下怎样推断两个链表是否存在相交的节点:
思路:
1、碰到这个问题,第一印象是採用hash来推断,将两个链表的节点进行hash。然后推断出节点,这样的想法当然是能够的。
2、当然採用暴力的方法也是能够的,遍历两个链表。在遍历的过程中进行比較,看节点是否同样。
3、第三种思路是比較奇特的,在编程之美上看到的。
先遍历第一个链表到他的尾部,然后将尾部的next指针指向第二个链表(尾部指针的next本来指向的是null)。这样两个链表就合成了一个链表。推断原来的两个链表是否相交也就转变成了推断新的链表是否有环的问题了:即推断单链表是否有环?
这样进行转换后就能够从链表头部进行推断了,事实上并不用。通过简单的了解我们就非常easy知道。假设新链表是有环的,那么原来第二个链表的头部一定在环上。因此我们就能够从第二个链表的头部进行遍历的,从而降低了时间复杂度(降低的时间复杂度是第一个链表的长度)。
下图是一个简单的演示:
这样的方法能够推断两个链表是否相交,但不太easy找出他们的交点。
4、细致研究两个链表。假设他们相交的话,那么他们最后的一个节点一定是同样的。否则是不相交的。因此推断两个链表是否相交就非常easy了。分别遍历到两个链表的尾部。然后推断他们是否同样,假设同样,则相交。否则不相交。
示意图例如以下:
在来看一下怎样找出第一个相交点:
思路:
1. 推断出两个链表相交后就是推断他们的交点了。如果第一个链表长度为len1,第二个问len2,然后找出长度较长的,让长度较长的链表指针向后移动|len1 - len2| (len1-len2的绝对值)。然后在開始遍历两个链表,推断节点是否同样就可以。
2. 另一种方案是,是在上面的问题中的解决方式3中将一个链表的尾节点链接到第二个链表的头结点。假设两个链表有共同的交点的话,一定存在环,那么这时候我们就能够找到环的入口节点,就是两个链表的相交的第一个节点。
总结
上面的几种方法中最后一种是比較不错的,当然hash也是能够的。
问题的延伸:
假设原来的两个链表中有环怎么处理?