博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面试题解(1):单向链表相关
阅读量:7195 次
发布时间:2019-06-29

本文共 2019 字,大约阅读时间需要 6 分钟。

从网上收集来的一些面试题和解题思路,加以整理,供参考。


问题0. 一个单向链表,请设计算法判断该链表中有没有环?

思路1:
声明一个指向链首的指针和一个足够大的int数组(或hash表,用于保存地址),逐个节点地遍历链表;遍历过程中,先判断该节点的地址是否已经在数组中存在了,如果不存在,则将该地址加入数组并让指针指向下一个节点;如果存在,则证明链表中有环。这种方法需要用数组来保存地址,并反复遍历该数组,效率很低,伪代码如下:

 1
Node 
*
 ptr 
=
 head;
//
链首
 2
int
 i[
100000
];
 3
int
 len
=
0
;
 4
while
(ptr 
!=
 
null
)
 5
{
 6    int address = ptr;
 7    if(address already in i)
 8    {
 9        print '链表中存在环';
10    exit();
11    }
12    i[len] = ptr;
13    ptr = ptr->next;
14}
15
print 
'
链表中没有环
'
16
exit();


思路2:
如果链表中有环的话,则整个链表呈6、9、或0字形;可以声明两个指向链首的指针,其中一个指针每次移动一个节点,另一个指针每次移动两个节点,如果两个指针指向同一个节点,则表示链表中存在环(类似与小学数学中的
追击问题
=_=),否则不存在环。伪代码如下:

 1
Node 
*
 ptr1 
=
 head;
 2
Node 
*
 ptr2 
=
 head;
 3
if
(ptr1 
!=
 
null
)
 4
    ptr1 
=
 ptr1
->
next;
 5
if
(ptr1 
==
 ptr2)
//
考虑链表中只有一个元素,且构成一个环的情况
 6
{
 7    print '链表中存在环';
 8    exit();
 9}
10
ptr2 
=
 ptr2
->
next
->
next;
//
或者ptr1->next;
11
while
(
true
)
12
{
13    if(ptr1==null || ptr2==null)
14    {
15        print '链表中没有环';
16        break;
17    }
18    if(ptr1==ptr2)
19    {
20        print '链表中存在环';
21        break;
22    }
23    ptr1 = ptr1->next;
24    if(ptr2->next != null)
25        ptr2 = ptr2->next->next;
26}
27
exit();


问题1. 两个单向链表,有可能交叉,请设计算法判断是否交叉,如果交叉,返回交叉点! 

思路:
两个单向链表交叉,则呈“Y”字型(存在环的话比较复杂,这里暂不考虑的存在环的情况),且链首在“Y”字形的上面分叉部分。于是可以先找到p1,p2的最后一个节点(各自遍历),同时记录节点数量a,b;然后判断最后一个节点是否相同,如果不相同则没相交;如果相同,则从一个节点和|a-b|+1个节点开始比较看是否相等,不相等都寻找下一个节点直到找到交叉点。伪代码如下:

int
 count1 
=
 
0
;
int
 count2 
=
 
0
;
Node 
*
 ptr1 
=
 head1;
Node 
*
 tail1 
=
 
null
;
Node 
*
 ptr2 
=
 head2;
Node 
*
 tail2 
=
 
null
;
while
(ptr1
!=
null
)
{
    tail1 
= ptr1;
    ptr1 
= ptr1 -> Next;
    count1
++;
}
while
(ptr2
!=
null
)
{
    tail2 
= ptr2;
    ptr2 
= ptr2 -> Next;
    count1
++;
}
if
(tail1 
!=
 tail2)
{
    print 
'两个链表没有交叉';
    exit();
}
ptr1 
=
 count1
>=
count2 
?
 head2 : head1;
ptr2 
=
 count1
>=
count2 
?
 head1 : head2;
int
 count 
=
 
0
;
int
 len 
=
 
|
count1
-
count2
|+
1
;
while
(ptr2
!=
null
)
{    
    count
++;
    
if(count== len)
        
break;
    ptr2 
= ptr2->Next;
}
while
(ptr2
!=
null
)
{
    
if(ptr2 != ptr1)
    
{
        ptr2 
= ptr2->Next;
        ptr1 
= ptr1->Next;
    }
    
else
    
{
        print 
'交叉点';
        exit();
    }
      
}


本文转自Silent Void博客园博客,原文链接:http://www.cnblogs.com/happyhippy/archive/2008/02/02/1062735.html,如需转载请自行联系原作者

你可能感兴趣的文章
Oracle新增监听以及创建实例
查看>>
上海MBA:精英从不止于前,离你造就非凡只差一个学位
查看>>
几种简单的求素数算法的复杂度分析
查看>>
shell脚本命令
查看>>
互融云:B2B电商供应链助力电商企业有效升级!
查看>>
Lagom零时:CQRS概念
查看>>
mysql-5.7.17-winx64免安装配置
查看>>
ubuntu+web.py+fastcgi+nginx
查看>>
配置YUM源,然后再安装补丁包
查看>>
万兆网卡在网吧服务器中的应用
查看>>
第五人格怎么投屏 轻松玩电脑版手游
查看>>
Hibernaate Set集合的使用
查看>>
推荐几个笔记类APP,自学提示必备
查看>>
Ruby中的Profiling工具
查看>>
Yii2语言国际化配置
查看>>
4分钟带你走进人工智能的辉煌时期
查看>>
判断输入为汉字的问题
查看>>
magento 银联插件 银行卡支付
查看>>
UEFI win7系统的安装
查看>>
Bootstrap Dialog 使用
查看>>