(剑指Offer)面试题37:两个链表的第一个公共结点
题目:
输入两个链表,找出它们的第一个公共结点。
链表结点的定义如下:
1 2 3 4 5 | struct ListNode{ int val; ListNode* next; ListNode( int x):val(x),next(NULL){}; }; |
思路:
1、暴力法
遍历第一个链表,每遍历到一个结点,在第二个链表中顺序遍历,如果在第二个链表上有一个结点和该结点一样,说明两个链表在这个结点上重合,也就是第一个公共结点。
时间复杂度:O(mn)
2、堆栈法
如果两个链表存在公共结点,那么从第一个公共结点到链尾,所有结点都是重合的,如果我们从两个链表的尾部开始往前比较,最后一个相同的结点就是第一个公共结点。
但单链表只有后继指针,不能往回移动,我们可以很快想到了栈,将两个链表的结点分别放入两个栈里,这样两个尾指针都在栈顶,接着下就比较栈顶指针是否相同,如果是,则把栈顶弹出,继续比较下一个栈顶,直至找到最后一个相同的结点。
时间复杂度:O(m+n),空间复杂度:O(m+n)
3、两个指针
首先分别遍历两个链表A,B,得到各自的长度如lenA,lenB,假设lenA>lenB,然后让A指针先走lenA-lenB步,接着两个指针一块走,直至相遇即找到第一个公共结点。
时间复杂度:O(m+n)
代码:
这里只实现方法3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | struct ListNode{ int val; ListNode* next; ListNode( int x):val(x),next(NULL){}; }; unsigned int GetListLength(ListNode* pHead){ unsigned int len=0; while (pHead!=NULL){ len++; pHead=pHead->next; } return len; } ListNode* FindFirstCommonNode(ListNode* pHead1,ListNode* pHead2){ unsigned int len1=GetListLength(pHead1); unsigned int len2=GetListLength(pHead2); ListNode* pLong=pHead1; ListNode* pShort=pHead2; unsigned lenDiff=len1-len2; if (len1<len2){ pLong=pHead2; pShort=pHead1; lenDiff=len2-len1; } for (unsigned int i=0;i<lenDiff;i++) pLong=pLong->next; while (pShort!=NULL && pLong!=NULL && pShort!=pLong){ pShort=pShort->next; pLong=pLong->next; } ListNode* pFirstCommonNode=pLong; return pFirstCommonNode; } |
在线测试OJ:
http://www.nowcoder.com/books/coding-interviews/6ab1d9a29e88450685099d45c9e31e46?rp=2
AC代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public : ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) { int len1=GetListLength(pHead1); int len2=GetListLength(pHead2); ListNode* pLong=pHead1; ListNode* pShort=pHead2; int lenDiff=len1-len2; if (len1<len2){ pLong=pHead2; pShort=pHead1; lenDiff=len2-len1; } for ( int i=0;i<lenDiff;i++) pLong=pLong->next; while (pLong!=NULL && pShort!=NULL && pLong!=pShort){ pLong=pLong->next; pShort=pShort->next; } ListNode* pFirstCommonNode=pLong; return pFirstCommonNode; } unsigned int GetListLength(ListNode* pHead){ unsigned int len=0; while (pHead!=NULL){ ++len; pHead=pHead->next; } return len; } }; |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步