面试题30:两个链表的第一个公共结点
来源:互联网 发布:知乎专栏有稿费吗 编辑:程序博客网 时间:2024/05/29 11:03
分析:从链表结点的定义看,两个链表是单向链表。如果两个单向链表有公共结点,那么这两个链表从某一结点开始,他们的m_pNext都指向同一个结点。从第一个公共结点开始,之后它们所有结点都是重合的,不可能再出现分叉。
例如:
方法一:分别把两个链表的结点放入两个栈中,这样两个链表的尾结点就位于两个栈的栈顶,然后比较两个栈顶的结点是否相同。若相同,则把栈顶弹出接着比较下一个栈顶,直到找到最后一个相同的结点。
空间复杂度:O(n1+n2), 因为需要两个辅助栈。时间复杂度:O(n1+n2)
方法二:首先遍历两个链表得到他们的长度,在第二次遍历时,在较长的链表上先走若干步,接着再同时在两个链表上遍历,找到第一个相同的结点就是他们的第一个公共结点。
时间复杂度:O(n1+n2), 不需要额外的辅助空间。
代码:
#include "stdafx.h"#include <iostream>#include <stack>using namespace std;//链表中的结点类型struct ListNode{int m_nKey;ListNode *m_pNext;};//创建一个链表,输入-1表示结束void CreateLinkedList(ListNode *&pHeadNode){bool isHeadNode = true;ListNode *pListNode = NULL;ListNode *pCurrentTail = NULL;while (1){if (isHeadNode){ pHeadNode = new ListNode();cin >> pHeadNode->m_nKey;pHeadNode->m_pNext = NULL;pCurrentTail = pHeadNode;isHeadNode = false;}else{pListNode = new ListNode();cin >> pListNode->m_nKey;if (pListNode->m_nKey == -1){break;}pListNode->m_pNext = NULL;pCurrentTail->m_pNext = pListNode;pCurrentTail = pListNode;}}}//求链表的长度int ListLength(ListNode *pHead){int nLength = 0; ListNode *pCur = pHead;while (pCur != NULL){nLength++;pCur = pCur->m_pNext;}return nLength;}//销毁一个链表void DestoryList(ListNode *pHeadNode){ListNode *pNode = pHeadNode;ListNode *pNext = NULL;while (pNode != NULL){pNext = pNode->m_pNext;delete pNode;pNode = pNext;} pHeadNode = NULL;cout << "链表已被销毁!" << endl;}//从头到尾打印链表void PrintList(ListNode *pHead){if (pHead != NULL){ListNode *pCurNode = pHead;cout << "从头到尾打印链表:"; while (pCurNode != NULL){cout << pCurNode->m_nKey << " ";pCurNode = pCurNode->m_pNext;}cout << endl;}}//从尾到头打印链表void PrintLinkedListReversely(ListNode *pHead){stack<ListNode *> tempStack;if (pHead != NULL){ListNode *pCurrent = pHead;ListNode *pStackNode = NULL;while (pCurrent != NULL){tempStack.push(pCurrent);pCurrent = pCurrent->m_pNext;}cout << "从尾到头打印链表:"; while (!tempStack.empty()){pStackNode = tempStack.top();cout << pStackNode->m_nKey << " ";tempStack.pop();}cout << endl;}}//找到两个链表的第一个公共结点ListNode *FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2){ListNode *pFirstCommonNode = NULL; int nLength1 = ListLength(pHead1);int nLength2 = ListLength(pHead2);int nLengthDiff = 0;//两个链表长度的差值ListNode *pLong = NULL;ListNode *pShort = NULL;if (nLength1 > nLength2){nLengthDiff = nLength1 - nLength2;pLong = pHead1;pShort = pHead2;}else{nLengthDiff = nLength2 - nLength1;pLong = pHead2;pShort = pHead1;}int i = 0;while (i < nLengthDiff){ pLong = pLong->m_pNext; i++;}while (pLong != NULL && pShort != NULL && pLong->m_nKey != pShort->m_nKey){pLong = pLong->m_pNext;pShort = pShort->m_pNext;}pFirstCommonNode = pLong;return pFirstCommonNode;}int _tmain(int argc, _TCHAR* argv[]){//创建第一个链表 ListNode *pHead1 = NULL;CreateLinkedList(pHead1);PrintList(pHead1); //创建第二个链表ListNode *pHead2 = NULL;CreateLinkedList(pHead2);PrintList(pHead2); cout << "两个链表的第一个公共结点是:" << FindFirstCommonNode(pHead1, pHead2)->m_nKey << endl;//销毁两个链表DestoryList(pHead1); DestoryList(pHead2);system("pause");return 0;}运行结果:
- 面试题30:两个链表的第一个公共结点
- 程序员面试题精选(56):找出两个链表的第一个公共结点
- 程序员面试题精选100题(35)-找出两个链表的第一个公共结点
- 程序员面试题精选100题(35)-找出两个链表的第一个公共结点
- 面试题37:两个链表的第一个公共结点
- 两个链表的第一个公共结点(面试题 37)
- 【剑指offer】面试题37:两个链表的第一个公共结点
- [剑指offer]面试题37:两个链表的第一个公共结点
- 剑指Offer:面试题37 两个链表的第一个公共结点
- 剑指offer 面试题37 两个链表的第一个公共结点
- 面试题37:两个链表的第一个公共结点
- 《剑指Offer》学习笔记--面试题37:两个链表的第一个公共结点
- 微软面试题之两个链表的第一个公共结点
- 面试题37:两个链表的第一个公共结点
- 【剑指Offer学习】【面试题37:两个链表的第一个公共结点】
- 面试题37_两个链表的第一个公共结点
- 剑指Offer面试题37(Java版):两个链表的第一个公共结点
- 面试题37:两个链表的第一个公共结点
- NVP1114B、NVP1118B、NVP1914以及NVP1918系列芯片
- UTF8与Unicode互转
- 如何在C/C++中动态分配二维数组
- __attribute__
- Android中Bitmap和Drawable
- 面试题30:两个链表的第一个公共结点
- JQuery操作checkbox
- hdu1054(二分图+最小点覆盖数+匈牙利算法)
- POJ 3714 最近点对
- 如何下载资源
- hdu 2050 折线分割平面
- 数据中心overlay
- java的double的精度问题
- 预编译头的使用