读《编程之美》有感—判断两个链表是否相交

请参照书P233-235.

这道题让我联想起几道关于单向链表的经典题目:

  1. 如果判断一个单项链表是否存在环?
  2. 已知一个单向链表存在环,如果找出该环的入口点?
  3. 已知两个链表相交,如何找出相交的第一个节点?
  4. 如果对一个单向链表进行反转?
  5. 已知一个单向链表,不知道该链表的头指针,已知一个节点的指针,如何将该节点从链表中删除?

题1:设置两个指针(p1, p2),初始值都指向头,p1每次前进一步,p2每次前进二步,如果链表存在环,则p2先进入环, p1后进入环,两个指针在环中走动,必定相遇。

题2:根据题1的结果,假定链表长为L,环长为c,链表头到入口点距离为x,入口点到相遇点的距离为y,z为相遇点回到入口点的距离。

L=x+y+z

假定p1,p2指针相遇时,p2指针在环中走了n圈,则有

x+y=nc

所以,x=nc-y=(n-1)c+(L-x)-y=(n-1)c+z

由公式得出:将p1指向表头,p2指向相遇点,p1,p2同时一步一步前进,当p1前进x步时,p1刚好在入口点,p2在前进了n-1个环后,也回到入口点,这时两个指针指向同一个节点,该节点就是入口点。

题3:题跟题2一样,可以将一个链表的尾节点指向另外一个,这样就问题2一样的解法了。当然,完成时,记得把指针重新置空。

另外一个办法,就是分别计算出两个链表的长度,分别为maxL,minL,分别设置指针p1,p2指向两个链表,p1指针指向长链表,p1先前进maxL-minL的距离,然后两个指针同时前进,当p1和p2指向同一个节点时,该节点即为相交的第一个节点,如果没有找到,就表示这两个链表不相交

题4:

解法一:可以设置三个指针,pre,cur,next,pre

node *pre=NULL;

node *next=NULL;

node *cur=head;

while(!cur)

{

next=cur->next;

cur->next=pre;

pre=cur;

cur=next;

}

解法二:使用递归

node *newRoot;

node *reverseNode(node *cur)

{

if(!cur || !cur.next)

{

newRoot=root;

return cur;

}

node *tmp= reverseNode(cur->next);

tmp->next=cur;

return cur;

}

题5:因为不知道链表的头指针,因此当前节点(B)如果被删除,链表将断裂,因此可以用一个指针指向当前节点(B)的下一个节点(C),然后将下一个节点复制到当前节点,这样当前节点数据就为下一个节点的数据了,而且指向了下下个节点,然后删除C节点。

 

附上《编程之美》该题的三页:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值