题目:输入两个链表,找出它们的第一个公共结点
来源:互联网 发布:单词朗读软件 知乎 编辑:程序博客网 时间:2024/05/29 11:54
题目:输入两个链表,找出它们的第一个公共结点。链表的定义如下:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
看到这道题的时候,很多人的第一反应就是采用蛮力的方法:在第一个链表上顺序遍历每个节点,每遍历到一个节点的时候,在第二个链表上顺序遍历每个节点。如果第二个链表上的节点和第一个链表上的节点一样,就说明两个链表在节点上重合,于是就找到了公共的节点。而通常蛮力并不是好的方法。
从链表的定义可以看出,这两个链表是单链表,如果两个链表有公共节点,那么这两个链表从某一节点开始,它们的m_pNext都指向同一个节点,之后它们所有的节点都是重合的,不可能再出现分叉。所以拓扑形状看起来是Y型。如下图所示:
一个简单的方法是:首先遍历两个链表得到它们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个节点。在第二次遍历的时候,先在较长的节点上走若干步,接着同时在两个链表上遍历,找到的第一个相同的节点就是它们的公共的节点。该算法的时间复杂度为:O(m+n)。
完整代码及其测试用例如下:
#include<iostream>using namespace std;struct ListNode{int m_nValue;ListNode* m_pNext;};//创建链表节点ListNode* CreateListNode(int value){ListNode* pNode = new ListNode();pNode->m_nValue = value;pNode->m_pNext = NULL;return pNode;}//连接链表节点void ConnectListNodes(ListNode* pCurrent, ListNode* pNext){if (pCurrent == NULL){//exit(1),非正常运行导致退出程序;exit(0),正常运行并退出程序cout << "Error to connect two nodes." << endl;exit(1);}pCurrent->m_pNext = pNext;}//销毁链表void DestroyList(ListNode* pHead){ListNode* pNode = pHead;while (pNode!=NULL){pHead = pHead->m_pNext;delete pNode;pNode = pHead;}}//销毁节点void DestroyNode(ListNode* pNode){delete pNode;pNode = NULL;}//求链表的长度unsigned int GetListLength(ListNode* pHead){unsigned int nLength = 0;ListNode* pNode = pHead;while (pNode!=NULL){nLength++;pNode = pNode->m_pNext;}return nLength;}//找第一个公共节点ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2){//求两个链表的长度unsigned int nLength1 = GetListLength(pHead1);unsigned int nLength2 = GetListLength(pHead2);//两个链表的长度差int nLengthDif = nLength1 - nLength2;ListNode* pListHeadLong = pHead1;ListNode* pListHeadShort= pHead2;if (nLength2 > nLength1){pListHeadLong = pHead2;pListHeadShort = pHead1;nLengthDif = nLength2 - nLength1;}// 先在长链表上走几步,再同时在两个链表上遍历for (int i = 0; i < nLengthDif; i++){pListHeadLong = pListHeadLong->m_pNext;}while ((pListHeadLong!=NULL)&& (pListHeadShort != NULL)&&(pListHeadLong != pListHeadShort)){pListHeadLong = pListHeadLong->m_pNext;pListHeadShort = pListHeadShort->m_pNext;}//得到第一个公共节点ListNode* pFisrtCommonNode = pListHeadLong;//ListNode* pFisrtCommonNode = pListHeadShort;也可以return pFisrtCommonNode;}// ====================测试代码====================void Test(char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected){if (testName != NULL){cout << testName << " begins: ";}ListNode* pResult = FindFirstCommonNode(pHead1, pHead2);if (pResult == pExpected){cout << "Succeed!" << endl;}else{cout << "Failed!" << endl;}}// 第一个公共结点在链表中间// 1 - 2 - 3 \// 6 - 7// 4 - 5 /void Test1(){ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ListNode* pNode6 = CreateListNode(6);ListNode* pNode7 = CreateListNode(7);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode6);ConnectListNodes(pNode4, pNode5);ConnectListNodes(pNode5, pNode6);ConnectListNodes(pNode6, pNode7);Test("Test1", pNode1, pNode4, pNode6);DestroyNode(pNode1);DestroyNode(pNode2);DestroyNode(pNode3);DestroyNode(pNode4);DestroyNode(pNode5);DestroyNode(pNode6);DestroyNode(pNode7);}// 没有公共结点// 1 - 2 - 3 - 4// // 5 - 6 - 7void Test2(){ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ListNode* pNode6 = CreateListNode(6);ListNode* pNode7 = CreateListNode(7);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode5, pNode6);ConnectListNodes(pNode6, pNode7);Test("Test2", pNode1, pNode5, NULL);DestroyList(pNode1);DestroyList(pNode5);}// 公共结点是最后一个结点// 1 - 2 - 3 - 4 \// 7// 5 - 6 /void Test3(){ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ListNode* pNode6 = CreateListNode(6);ListNode* pNode7 = CreateListNode(7);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode7);ConnectListNodes(pNode5, pNode6);ConnectListNodes(pNode6, pNode7);Test("Test3", pNode1, pNode5, pNode7);DestroyNode(pNode1);DestroyNode(pNode2);DestroyNode(pNode3);DestroyNode(pNode4);DestroyNode(pNode5);DestroyNode(pNode6);DestroyNode(pNode7);}// 公共结点是第一个结点// 1 - 2 - 3 - 4 - 5// 两个链表完全重合 void Test4(){ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode5);Test("Test4", pNode1, pNode1, pNode1);DestroyList(pNode1);}// 输入的两个链表有一个空链表void Test5(){ListNode* pNode1 = CreateListNode(1);ListNode* pNode2 = CreateListNode(2);ListNode* pNode3 = CreateListNode(3);ListNode* pNode4 = CreateListNode(4);ListNode* pNode5 = CreateListNode(5);ConnectListNodes(pNode1, pNode2);ConnectListNodes(pNode2, pNode3);ConnectListNodes(pNode3, pNode4);ConnectListNodes(pNode4, pNode5);Test("Test5", NULL, pNode1, NULL);DestroyList(pNode1);}// 输入的两个链表都是空链表void Test6(){Test("Test6", NULL, NULL, NULL);}int main(){Test1();Test2();Test3();Test4();Test5();Test6();system("pause");return 0;}
运行结果:
Test1 begins: Succeed!
Test2 begins: Succeed!
Test3 begins: Succeed!
Test4 begins: Succeed!
Test5 begins: Succeed!
Test6 begins: Succeed!
请按任意键继续. . .
0 0
- 题目:输入两个链表,找出它们的第一个公共结点
- 输入两个链表,找出它们的第一个公共结点。
- 【剑指offer】输入两个链表,找出它们的第一个公共结点。
- 输入两个链表,找出它们的第一个公共结点
- 输入两个链表,找出它们的第一个公共结点
- 28.输入两个链表,找出它们的第一个公共结点。
- 输入两个链表,找出它们的第一个公共结点
- 输入两个链表,找出它们的第一个公共结点。
- 输入两个链表,找出它们的第一个公共结点
- 输入两个链表,找出它们的第一个公共结点。
- 输入两个链表,找出它们的第一个公共结点
- 剑指offer:两个链表的第一个公共结点输入两个链表,找出它们的第一个公共结点。
- 两个单向链表,找出它们的第一个公共结点
- 两个单向链表,找出它们的第一个公共结点
- 两个单向链表,找出它们的第一个公共结点
- 两个单向链表,找出它们的第一个公共结点。
- 两个单向链表,找出它们的第一个公共结点。
- 两个单向链表,找出它们的第一个公共结点
- Easy 349题 Intersection of Two Arrays
- 数据结构实验之串三:KMP应用
- 两种IO模式:Proactor与Reactor模式
- 如何将mltbx文件导入matlab
- 一些学习笔记,仅作本人记录之用
- 题目:输入两个链表,找出它们的第一个公共结点
- NOIP2016 暑期培训 D4
- 百分比布局中的与GridView
- java虚拟机原理浅析
- poj2752 Seek the Name, Seek the Fame
- hdu 5538 House Building(长春现场赛)
- 51nod:1049 最大子段和
- C/C++零碎集——第二集
- 148.View the Exhibit. Which statements are true regarding the USERS tablespace? (Choose all that app