今天去微软面试,微软出了一道这样的题目.

cplusplus8848 2008-10-20 07:13:03
请问有没有好的算法..
There are 2 singlelinks.
And there might be crossusage in the links.
Please try to program to identify whether there are nodes used by both singlelinks.

e.g.: (for following node, use (next node address, value) style)
Single Node1:
(0FF00AA, 3)->(0DE3AB2, 7)->(037BFAE, 9)->(NULL, 8)

Single Node2:
(07733A3, 7)->(037BFAE,3)->(NULL, 8)

so, in this sample, from the last node (NULL, 8), the singlelink begin cross linked.
So, our target is to verify whether there are cross linked condition in given 2 singlelinks.

Consider the data structure in C# is hard to implement the singlelink,
This question should be implemented in C++ or C.
...全文
836 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunhuanwen 2008-10-21
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 qinqinhao 的回复:]
编程之美
[/Quote]

这么美
dingyanan 2008-10-21
  • 打赏
  • 举报
回复
能不能在连表中增加一个表示是否被访问的数据成员 :bool tag;均初始化为false,?

遍历链表A;并将tag=true;

遍历链表B:看看tag是不是为true?

zwd2005 2008-10-21
  • 打赏
  • 举报
回复
mark
dingyanan 2008-10-21
  • 打赏
  • 举报
回复
没有顺序呀
aaajj 2008-10-21
  • 打赏
  • 举报
回复
有意思
fulton_xc 2008-10-21
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 bitxinhai 的回复:]
看看最后一个节点是不是一样就行了!!!
[/Quote]
同意,题目要求定性判断即可。
baihacker 2008-10-21
  • 打赏
  • 举报
回复

我给的是空间复杂度为O(1),时间复杂度为O(n)的解...其它解没兴趣.
n为max(表A长度,表B长度)
xxgamexx 2008-10-21
  • 打赏
  • 举报
回复
mark
baihacker 2008-10-21
  • 打赏
  • 举报
回复



解法一:
//忽略参数合法性检查,譬如ab是否为null,他们是否循环链表等等
node* find_conflict(node* a , node* b)
{
int lenA=0,lenB=0;
//计算a长度,O(n)
{
node* current=a;
while(current)
{
lenA++;
current=current->Next;
}
}
//计算b长度,此处如果必要的话,可以被抽象成GetLength函数,O(n)
{
node* current=b;
while(current)
{
lenA++;
current=current->Next;
}
}
//跳过比较长的链表的|lenA-lenB|个节点,O(n)
if(lenA>lenB)
{
while((lenA--)>lenB)
a=a->Next;
}
else
{
while((lenB--)>lenA)
b=b->Next;
}
//一个一个配对比较,如果发现相等则返回节点。此时a和b一样长,O(n)
while(a)
{
if(a==b)
{
return a;
}
else
{
a=a->Next;
b=b->Next;
}
}
return 0;//找不到交点,返回空
}
算法复杂度:四步都是O(n),而且因为他们是顺序的,于是取和,结果依然是O(n)

图示:
假设a b如下
A:1 2 3 4
7 8 9 10
B: 5 6
链表A=1 2 3 4 7 8 9 10
链表B=5 6 7 8 9 10
第一个交点明显是7。根据以上算法

第一步:算出lenA=8
第二步:算出lenB=6
第三步,由于lenA>lenB,于是让A跳过lenA-lenB个节点,此时A指向3
第四步,依次比较:
5!=3
6!=4
7==7,返回7








解法二:
求第一个相交结点算法:
  两个单向链表的尾部重合,返回第一个相交结点。a, b分别为这两个单向链表的头结点。本算法假设无非法数据传入,至少有一个重合的结点。
算法:
S1:就地翻转链表a,并将其结点个数存入变量L1,翻转后的链表头为c;
S2:就地翻转链表b,并将其结点个数存入变量L2,翻转后的链表头为a;
S3:就地翻转链表c,并将其结点个数存入变量L3,翻转后的链表头为b;
S4:记A=[1 0 1; 1 1 0; 0 1 1] X = (X1, X2, X3)' L = (L1, L2 L3)' 解方程AX=L;
S5:返回链表a中指向第X1+1个元素的指针。
正确性:
  方程AX=L显然有解。(对于其它特殊情况也成立,稍加修改就能适应所有可能)
复杂度:
  显然只需要额外的变量L,c,X(其中X2,X3可以不要),以及翻转链表中的一些指针, 空间复杂度O(1);
  时间复杂度明显为O(N);(翻转操作不会超过3n,寻找结点不会超过n,解方程为常数,因为系数矩阵已经知道了)。
fulton_xc 2008-10-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lenic 的回复:]
就是求两个单链表是否交叉嘛~有交叉的话,结尾一定是同一个节点吧~

如果是求交叉点,有两种方法:
方法一:使用两个栈,遍历两个链表的同时依次压栈,最后弹栈直到节点不同,即求出相交节点。

方法二:使用两个指针p1,p2,一开始,p1遍历list1,p2遍历list2,同时走;
当p1到达list1尾部时,重新从list2遍历;
当p2到达list2尾部时,重新从list1遍历;
这个过程中一直比较p1==p2,若 相等则表示该节点是交叉节点,…
[/Quote]
方法二在p1=p2后,仍然要遍历到尾部,中间可能有部分p1!=p2,要判断最后不等的位置以确定相同部分起始位置,这样就可以找出相同部分所有点(起始位置即可)。
insulted 2008-10-21
  • 打赏
  • 举报
回复
15楼正解
swungle 2008-10-21
  • 打赏
  • 举报
回复
学习中啦!!
lsd1025 2008-10-21
  • 打赏
  • 举报
回复
学习
李冬宝 2008-10-21
  • 打赏
  • 举报
回复
终于想明白了,呵呵。
李冬宝 2008-10-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lenic 的回复:]
就是求两个单链表是否交叉嘛~有交叉的话,结尾一定是同一个节点吧~

如果是求交叉点,有两种方法:
方法一:使用两个栈,遍历两个链表的同时依次压栈,最后弹栈直到节点不同,即求出相交节点。

方法二:使用两个指针p1,p2,一开始,p1遍历list1,p2遍历list2,同时走;
当p1到达list1尾部时,重新从list2遍历;
当p2到达list2尾部时,重新从list1遍历;
这个过程中一直比较p1==p2,若 相等则表示该节点是交叉节点,…
[/Quote]

第二种想法的思路是什么呢?有点高深啊
qinqinhao 2008-10-21
  • 打赏
  • 举报
回复
编程之美
cnmmbd 2008-10-21
  • 打赏
  • 举报
回复
看看
qinqinhao 2008-10-21
  • 打赏
  • 举报
回复
ding
cattycat 2008-10-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lenic 的回复:]
就是求两个单链表是否交叉嘛~有交叉的话,结尾一定是同一个节点吧~

如果是求交叉点,有两种方法:
方法一:使用两个栈,遍历两个链表的同时依次压栈,最后弹栈直到节点不同,即求出相交节点。

方法二:使用两个指针p1,p2,一开始,p1遍历list1,p2遍历list2,同时走;
当p1到达list1尾部时,重新从list2遍历;
当p2到达list2尾部时,重新从list1遍历;
这个过程中一直比较p1==p2,若 相等则表示该节点是交叉节点,…
[/Quote]
第二个办法好,跟15楼办法4一样,如果交叉可以求出交叉的起始节点。复杂度O(m+n).
banqhu 2008-10-21
  • 打赏
  • 举报
回复
mark
加载更多回复(22)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧