面试题集-链表

如何准备

链表是面试中非常常见的问题。问题难度有难有易。无论题目如何,我们都建议你先练熟简单题目。掌握了简单链表题,面对那些难题的时就会轻松一点。所以下面列出了一些链表题中必备的代码。

创建一个链表:

注意:在面试的时候写链表,一定要先问清楚是写单链表还是双链表!

在单链表中删除一个节点

2.1从一个未排序的链表中删除重复元素
进阶:如果不能使用额外的空间怎么办?
2.1解答:
如果可以使用哈希表的话,那么检查每一个元素是否重复,然后移除。

如果不能额外使用空间的话,我们就需要两个指针来遍历数组:current用来正常的遍历;runner则用来检查元素是否重复。runner只为一个元素检查一次是否重复,因为每一次runner会删除和元素的所有重复元素。

2.2 实现算法查找单链表中的倒数第n个元素。
注意:这个问题强烈的暗示递归算法,但是这里才采用一种更巧妙的方法。像这样类似的问题就,一定要多思考看看。能不能用非递归的方法代替递归的方法。
2.2解答:
这里我们假设链表的长度至少为n。
算法描述:
(1) 创建两个指针p1和p2,均指向链表头。
(2) 让p2增加n-1次,使得p2指向从链表头第n个元素(使得p1和p2之间距离为n)
(3) 若p2->next为空,则返回p1;不为空则同时增加p1,p2。(如果p2->next为空,则表示p1所指的元素为倒数第n个,因为p1,p2的距离为n。)
(4) 重复(3)

2.3 实现一个算法,只给你链表中间的一个元素(没有链表头),将其从链表中删除。
例如:
输入:节点 c (原链表为 a->b->c->d->e)
输出:没有任何返回值。但链表变成 a->b->d->e
2.3解答:
本题的解答只是把输入的下一个元素拷贝到输入的这个元素中以完成删除输入的元素。(译者注:原文的代码没有释放下一元素的空间。)
注意:这样的方法并不能删除链表的最后一个元素。这一点需要和你的面试官说清楚。算法有缺陷没有关系,大胆的告诉你的面试官,他们喜欢看到你提出这些。至于怎么解决可以和你的面试官讨论。
 

2.4 两个用链表表示的数字,最低位在表头。写一个函数对两个这样的链表求和,采用相同的形式返回结果。
例如: (3 -> 1 -> 5) + (5 -> 9 -> 2)  返回  8 -> 0 -> 8
2.4解答:
本题可以采用递归的方式逐位的做加法。算法流程:

2

2.5 给一个带有环的链表,设计算法查找这个环的起点。
环的定义:链表中的某一元素的下一个元素为之前的一个元素。
例如:输入 A -> B -> C -> D -> E -> C 输出 C
2.5 解答:
如果在链表中有两个指针,从表头开始p1以每次一个节点的速度前进,p2每次2个。那么这两个指针一定在链表的环中相遇。想想两辆车以不同的速度在一个环形跑道上运动,那么他们肯定会在跑道上再次相遇。
这个问题最难的部分就在于如何超出这个环开始的节点。假想下如果是在一个圆形的跑道上p2以两倍的速度于p1同时从起点出发,他们将会哪里相遇。还是在起点!
现在我们再假设如果p2超前起跑线k米起跑,他们第一次在哪里相遇呢?在起跑线后面k米处。(为什么?假设p2过了起跑线之后跑了x和p1相遇,那么p2跑了l-k+x,其中l为跑道的长度,至相遇时p1也跑了x。根据相遇时消耗的时间相等得方程 (l-k-x)/2=x/1,解得 x = l-k,也就是在起跑线后k处相遇。)

那重新回到问题本身,当p1指针刚进入环的时候,p2在环中恰好领先p1指正k个节点,k为链表头节点到环开始处的距离。根据之前的结论,当p1、p2相遇的时候,他们都相遇环开始节点k个距离。
那么我们得到如下结论:
(1)表头距离环开始处k节点
(2)p1,p2距离环开始处也是k个节点。
如果当p1、p2相遇之后,将p1至于表头然后两个指针都采用1的速度移动的话。那么相遇处即为环开始处。 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值