一、问题描述
编写一个程序来查找两个单独链接列表的交集开始的节点。
例如,以下两个链表:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
开始在节点c1相交。
【提示】
如果两个链表完全没有交集,则返回null。
链接列表在函数返回后必须保留其原始结构。
您可能会认为整个链接结构中没有任何地方的循环。
您的代码应该最好在O(n)时间内运行,并只使用O(1)内存。
二、解题思路
思路一:一次重定向,再逐一比较 -- O(m+n)
1)将A重定向到B,得到一个新链表
2)将B重定向到A,得到一个等长的新链表
3)遍历这两个新链表,如果同时为空,说明并不会相交,
如果找到相同的元素,则该元素就是相交的元素
思路二:先补链表长度差,再逐一比较 -- O(m+n)
1)首先遍历两个链表得到他们的长度,就能知道哪个链表比较长,以及长链表比短链表多几个结点
2)第二次遍历时,在较长的链表上先走若干步,接着再同时在两个链表上遍历,找到第一个相同的结点就是他们第一个公共结点。
三、解题算法
思路一:一次重定向,再逐一比较
/*************************************************
Author:tmw
date:2018-4-14
*************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct listnode
{
int data;
struct listnode* next;
}listnode;
listnode* getIntersectionNode( listnode* headA, listnode* headB )
{
/**入口检查:当两者任意一个为空,则返回NULL**/
if( headA == NULL || headB == NULL )
return NULL;
else
{
listnode* pa;
listnode* pb;
pa = headA;
pb = headB;
int flagA = 0;
int flagB = 0;
while( pa && pb ) /**约定链表没有头指针,首位即存有值**/
{
if( pa->data == pb->data )
return pa;
pa = pa->next;
pb = pb->next;
/**将A重定向到B,得到一个新链表**/
/**flagA用于只重定向一次,避免程序重复重定向而死循环了**/
if( pa == NULL && flagA == 0 )
{
pa = headB;
flagA = 1;
}
/**将B重定向到A,得到一个等长的新链表**/
/**flagB作用同flagA**/
if( pb == NULL && flagB == 0 )
{
pb = headA;
flagB = 1;
}
}
/**还没找到,则说明两个链表没有交点**/
return NULL;
}
return NULL;
}
思路二:先补链表长度差,再逐一比较 -- O(m+n)
/**
* 解法二:先补链表长度差,再逐一比较
**/
int listNodeLength( listNode* head )
{
int len = 0;
listNode* p = head;
while(p)
{
len++;
p = p->next;
}
return len;
}
listNode* findFistCommomNodeMethod1( listNode* head1, listNode* head2 )
{
if( head1==NULL || head2==NULL ) return NULL;
int len1 = listNodeLength(head1);
int len2 = listNodeLength(head2);
int gap = len1 - len2;
//保证pLong始终指向的是长度长一点的链表,pShort指向的是长度短一点的链表
listNode* pLong = head1;
listNode* pShort = head2;
if( len1 < len2 )
{
pLong = head2;
pShort = head1;
gap = len2 - len1;
}
//长链表先走
int i;
for( i=0; i<gap; i++ )
pLong = pLong->next;
//此时长链表和短链表的同时开始挪动
while( pLong != NULL && pShort != NULL && pLong->data != pShort->data )
{
pLong = pLong->next;
pShort = pShort->next;
}
return pLong;
}
梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~~