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

时间:2022-10-04 11:01:37

首先遍历得到两个链表的长度,得到差值dif,较长的链表先移动dif步,然后同时在两个链表上便利,第一个相同的结点就是第一个公共结点


#include<iostream>
using namespace std;

struct ListNode
{
int m_nValue;
ListNode *m_pNext;
};

ListNode *CreateListNode(int value)
{
ListNode *node = new ListNode();
node->m_nValue = value;
node->m_pNext = NULL;
return node;
}

void ConnectListNodes(ListNode *head,ListNode *next)
{
if(head!=NULL)
{
head->m_pNext = next;
}
}

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;
}
int getListLength(ListNode * pHead)
{
ListNode *pNode = pHead;
int len=0;

while(pNode!=NULL)
{
len++;
pNode=pNode->m_pNext;
}
return len;
}
ListNode * FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2)
{
int pHead1Len = getListLength(pHead1);
int pHead2Len = getListLength(pHead2);

int difLen = pHead1Len - pHead2Len;
ListNode* pLong = pHead1;
ListNode* pShort = pHead2;

if(difLen<0)
{
difLen = - difLen;
pLong = pHead2;
pShort = pHead1;
}

for(int i=0;i<difLen;i++)
pLong = pLong->m_pNext;

while((pLong!=NULL) && (pShort!=NULL)&& (pLong!=pShort))
{
pLong = pLong->m_pNext;
pShort = pShort->m_pNext;
}

ListNode *pFirst = pLong;
return pFirst;
}
// ====================测试代码====================
void Test(char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected)
{
if(testName != NULL)
printf("%s begins: ", testName);

ListNode* pResult = FindFirstCommonNode(pHead1, pHead2);

if(pResult == pExpected)
printf("Passed.\n");
else
printf("Failed.\n");
}

// 第一个公共结点在链表中间
// 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 - 7
void 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(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();

return 0;
}