求链表的第一个公共节点问题(好未来笔试题)

问题描述:给定两个链表的头指针,判断两个链表是否存在公共节点,如果存在公共节点,则找出第一个公共节点。

分析:这曾经是我参加好未来的一道笔试题目,给大家分享下解法。

解法一:蛮力法。拿第一个链表的每个节点去和第二个链表的每个节点进行比较,如果都不相同,则判断出两个链表不相交。

否则输出第一个相同的节点。算法的时间复杂度为O(m*n).

解法二:辅助空间法。仔细观察可以发现,如果两个链表想要相交,则尾节点必是相交点,否则不相交。

因此我们可以从两个链表的尾部开始进行比较,如果不相同,直接判断出不相交。

如果相同,记下这个节点,然后继续往前比较,如果仍然相同,记下这个节点,如此进行下去,直到碰到不同的节点为止,

那上次保存的节点就是第一个相交的节点。但是由于单链表只能从头开始遍历,不能从尾部向头遍历,需要采用一些办法来实现,

这个属于典型的先进后出,因此可以使用栈来实现,需要利用两个辅助栈实现,首先将两个链表中的所有节点入栈,然后再从栈顶开始比较。

算法的时间复杂度为O(m+n).

解法三:  由于解法二需要额外的辅助空间,可以再加以改进。

可以先将两个链表扫描一遍求出各自的长度为m和n,并假设m>=n,这样,可以先在长的链表上遍历m-n个节点,然后再在两个链表上同时开始遍历,

并比较节点是否相同,如碰到第一相同的节点,就可以结束了,如果遍历完都没有相同的节点,那么就可以判断出,两个链表没有交点。

算法的时间复杂度为O(m).

由于比较简单,我就不再些具体的代码了,读者可以自行验证。

时间: 2024-11-05 12:20:49

求链表的第一个公共节点问题(好未来笔试题)的相关文章

求链表的第一个公共节点

求链表的第一个公共节点主要思想 有如下两个链表: 有以下两种方法 上述链表,有一种蛮力方法,就是从一个链表中每一个节点,与另外链表中的节点,去比较, 如果从中找到相同的节点,表示有公共节点,这个算法时间复杂度为O(n*m),两个链表的长度分别为n,m 如果使用快慢指针,让链表长的指针,先走,走的步数就为,两者长度差,如果两者有相同节点,必然会在一个地方,相遇, 该算法的时间复杂度为O(max(n,m)) 方法2 的实现代码为: /* struct ListNode { int val; stru

剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)

思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到链表的长度风别为,len1和len2,求出两者的差值dif,然后现在长的链表上面走dif步,然后同步走剩下的节点,当就可以找到第一个公共节点了. public ListNode findFirstCommonNode(ListNode pHead1,ListNode pHead2){ if(pHea

找出链表的第一个公共节点

62.找出链表的第一个公共结点.题目:两个单向链表,找出它们的第一个公共结点 思路: 1.暴力法 但时间复杂度太高 o(n*m) 2.如果两个链表有公共节点,则从该公共节点起,后面的节点均为公共的,即这两个链表在第一个公共节点交叉,然后形成一个Y字型,因为两个链表长度不一定一样,所以可以先求得他们的长度n与m,然后得到长度差:Math.abs(n-m),然后先对较长链表先行遍历n-m个节点,从第n-m+1个节点开始对这两个链表遍历,然后找出第一个相同的即可  (网上抄别人的) 3. 位图法 对两

找到两个链表的第一个公共节点 37

? ? 引言 ? ? 这个问题一种常想到的方法就是两层循环遍历,外层循环遍历链表A,对A中每个节点,遍历链表B,如果在B中找到,说明这个节点是第一个公共节点,但是这样的方法时间复杂为mn,一般是不允采用的 ? ? 分析问题 ? ? 所以我们需要分析更深层次的问题,找到其中的规律,我们如果动手画一下一般的链表图就能够发现两个链表的第一个公共节点之后的样子一定是如下表示(由此可以发现有时候动手是很重要的) ? ? ? ? 可以发现两个链表在第一个节点重合之后不会再分开了 ? ? 简单多说一句不会分开

经典算法学习——打印两个链表的第一个公共节点

求链表的公共节点是一道很经典的算法题,并不是很难.我们需要知道的是,一旦两个链表有一个公共节点的话,那么这两个链表的形状就是一个"Y"型.也就是说,自公共节点之后的所有节点都是一样的.如下: 其实只要看了这幅图,实现就很简单了.首先我们分别遍历两个链表,分别得出他们的长度L1,L2.然后在查找公共节点时,先在长的那个链表中走|L1-L2|步,然后两个链表同时向后进行同步遍历,每走一步时,就判断后面那个节点是否相同.若相同,则找到该第一个公共节点.完整代码上传至 https://gith

37 - 两个链表的第一个公共节点

题目描述: 输入两个链表,找出它们的第一个公共结点. 如:第一个公共节点为值为 6 的节点. 相关题型:在二叉树中找出两个节点的最低公共祖父节点.使用的算法是:找出根到2个节点的路径,然后从根遍历,当最后一个相同的节点,即为最低公共祖父节点. 思路一: 在本题中,如果我们能从最后 1 个节点(如bst中的根) 向前遍历,则很容易找出第一个公共节点,但是单链表只能从前向后遍历.而给定从前到后,如何得到从后向前,可以想到使用先进后出的栈. 因此我们可以用2个栈存储2个链表的节点,然后从栈顶开始逐个比

36.两个链表的第一个公共节点。

题目描述: ??输入两个链表,找出它们的第一个公共结点. 思路分析: ??由于链表的指针只能指向一个节点,所以两个链表相交后,后面的部分完全一样.所以我们的解题思路就是先求出两个链表的长度,设置俩个指针分别指向两个链表的头部.指向较长链表的指针先走两个链表长度差步,然后两个指针同时开始走,当两个指针指向同一个节点时,这个节点就是第一个公共节点. 代码: /* public class ListNode { int val; ListNode next = null; ListNode(int v

【剑指offer】52、两个链表的第一个公共节点

题目 输入两个链表,找出它们的第一个公共结点. 思路一 因为是反向找,所以会想到用栈.将两个链表都压入两个栈,然后反向弹出,找出第一个公共节点.思路很简单 class Solution { public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { stack<ListNode*> s1, s2; if (pHead1 == nullptr || pHead2 == nullptr) return n

52-两个链表的第一个公共节点

题目:输入两个链表,找出它们的第一个公共节点. def first_common_node(head1,head2): p1,p2 = head1,head2 cnt1,cnt2=0,0 while p1: cnt1 +=1 p1=p1.next while p2: cnt2 +=1 p2=p2.next p1, p2 = head1, head2 if cnt1>cnt2: for i in range(cnt1-cnt2): p1=p1.next if cnt2>cnt1: for i i