您的位置:首页 > 职场人生

微软面试百题007——链表相交

2016-08-11 09:56 190 查看

1.题目描述:

给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如何判断链表存在环
2.如果需要求出俩个链表相交的第一个节点列?

2.求解:

1.如何判断链表带环
我们加入两个指针,一个快指针,一个慢指针,快指针一次前进2个单位,慢指针一次前进一个单位
如果不存在环的话快指针会先扫描到NULL
如果存在环的话,快指针总是会和慢指针相遇(有的人可能会疑惑会不会刚好错过,仔细想一下会发现,没有入环之前两者距离不断增加1,如幻之后两者距离不断缩短1,必然会相遇)
bool move(point* slow,point* fast)
{
while(fast!=NULL&&fast!=slow)
{
slow=slow->next;
fast=fast->next;
if(fast!=NULL) fast=fast->NULL;   //这一句一定要小心
else break;
}
if(fast==NULL) return 0;
else return 1;
}


2.如何快速判断环的入口点:
数学表达式计算:
L——链表的长度
A——链表头到环入口的距离
S——环入口到快慢指针相遇处距离
R——环长(R=L-A)
L-A-S——相遇处到环入口的距离

设慢指针走了K步,快指针走了2*K步
显然:K=nR
A+S=K=nR=(n-1)R+R=(n-1)R+L-A
A=(L-A-S)+(n-1)R
根据上面的共识我们会发现,只要我们在链表的开头和相遇点之处再假设同步的指针,分别向后移动,可定会在环入口点相遇
point* find(point* head,point* meet)    //已经确认有环
{
while(head!=meet)
{
head=head->next;
meet=meet->next;
}
return head;
}


3.判断是否链表相交(相交后,之后的节点都是重合的)



1.最老的方法:O(n*n)选定一个节点之后我们去遍历另一个节点,每一次都遍历一遍,复杂度太高
2.将其中一个链表首尾相交,便利另一个链表如果可以扫描到已经相交的链表的头的话,说明相交,否则不相交
3.着第一个相交点:计算两个链表的长度差,指针弥补长度差,同时开始同步移动
4.hash法:
通过遍历一条链表,将内存地址哈希化,然后扫面另一个俩表寻找就可以了(目前还真不会哈希化内存地址)
http://blog.csdn.net/zhoudaxia/article/details/8884402

3.遗留重要问题:

我们怎么做才可以把内存地址当作关键字自己设定哈希函数来哈希化,求教
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: