【过去酒逢知己千杯少,现在酒逢千杯知己少】
突然不知道怎么写开场白了,因为我被一个OJ题的浪漫小情调给感动了,一起看看是我泪点太低还是真的浪漫。
原题如下:
题目:
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 NULL。
题目数据保证整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
进阶:你能否设计一个时间复杂度 O(n) 、仅用 O(1) 内存的解决方案?
先来说说我看了这个题目的感觉:
这个题感觉有迷惑性,有让人猜的意思。先来补充几个概念:
头指针:指向链表中第一个结点地址的指针
头结点:是在链表的首元结点之前附设的一个结点,头结点指针域中存储首元结点的地址。
首元结点:链表中存储第一个数据元素的结点
如果你按照这些定义去解这个题,当然是偏离方向的。而它这里所要表达的意思就是头指针,而并非头结点。还有所给的一些例子,所描述的并没有问题,然而对你解题却是没有什么价值。不过又站在另外一个角度想,这也是锻炼你提取重要信息的能力,当然这是好事啦,所以也还是仁者见仁智者见智。好吧接下来进入正题。
审题:
1.两个单链表可能存在相交,相交返回相交的起始节点,不相交返回NULL;
2.链表不存在环;
3.不能改变原始结构;
4.时间复杂度为O(n),空间复杂度为O(1)。
可能给我们的链表情况:
1.其中一个是空单链表;
2.两个都是空单链表;
3.都有结点,但不存在相交;
4.都有结点,且存在相交。
现实版
对于前两种情况都很好处理,直接返回NULL即可,关键在于后面两种情况,因为要求空间复杂度为O(1)就不能借助额外空间,那么在不借助其它空间的前提下该如何进行判断?
能否通过结点元素来进行判断?不能,因为根据题目给的例子,两链表在不相交的时候是完全可能存在具有相同数据元素的结点。
能否依次拿其中一个链表的结点地址和另外一个链表的结点地址依次进行比较?不能,这种方法的时间复杂度为O(n^2)不满足时间复杂度为O(n)。
其实本题核心问题就是要处理两单链表的结点数目可能不相等,那能不能先计算出个自的结点数目,判断谁的结点多,多几个,结点多的单链表先让它往前面走其多的结点数目,再依次进行比较看是否存在相同地址的结点。这个似乎是可行的,时间复杂度和空间复杂度都满足。对于结点数目相同,能够理解,来看看结点数目不相同是什么情况。
有图有真相:
A单链表的结点数目5个结点,B单链表的结点数目为7个结点,B单链表比A单链表多2个结点,我们让指示B单链表的指针先走2个结点,如下图:
<