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

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法:
通过遍历一条链表,将内存地址哈希化,然后扫面另一个俩表寻找就可以了(目前还真不会哈希化内存地址)

3.遗留重要问题:

我们怎么做才可以把内存地址当作关键字自己设定哈希函数来哈希化,求教
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值