算法与数据结构面试题(7)-链表“香蕉”问题
2014-12-14 13:32
387 查看
题目
微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交。 为了简化问题,我们假设俩个链表均不带环。 问题扩展: 1.如果链表可能有环列? 2.如果需要求出俩个链表相交的第一个节点?
解题思路
1.先了解一下什么是有环链表2.查找判断是否相交的方法
3.求出列表相交的第一个节点。
解题步骤
1.有环链表
有环的链表指的是链表有环路,例如下面:A->B->C->D->B,这样遍历的时候B->C->D->B就形成一个环路一直循环。环链表
上面的知识中讲解了如何判断单向链表是否含有环。有三种方式:
1.第一种方式很好理解,就是用散列表数据结构中来保存已遍历的节点,如果当前遍历的节点存在于上面的数据结构中,那说明存在环。 时间复杂度O(n)
2.指针反转:指能通过表尾部节点找到表头的链表。在有环的情况下,表指针会通过反转找到表头,那么遍历完成后,只需要判断最后一个节点是否是标头就行。时间复杂度为O(n),但是该方法破坏了表的结构,遍历结束后,需要还原。
3.快慢指针:fast指针移动2个位置,slow指针每次移动一个指针,如果在某一个位置中,快慢指针如果能相遇,说明有环。
2.是否相交
链表相交1.直接法:循环遍历链表1种所有节点,然后再判断该节点是否存在于链表2种。时间复杂度O(n2).
2.利用计数。有点复杂,需要消化。
以节点地址遍历第一个链表,保存所有地址到一个hash表中
遍历第二个链表,判断当前节点的地址是否存在于上面的hash表中
如果存在,则有相交
时间复杂度O(n).
3.利用最后一个节点:如果相交的话,那么最后一个节点肯定是相同的。那么每个链表只需要遍历到最后一个节点,然后比较2个最后节点的地址是否相同就ok啊。时间复杂度O(n).
总结:判断是否有环用方法3,是否相交用方法2。求第一个相交节点也就方便许多。
代码
public class Banana {//保存相交节点
LinkedListNode bananaNode = null;
/**
* 判断链表是否有环
*/
public boolean isLoop(LinkedListNode node) {
LinkedListNode fastNode;
LinkedListNode slowNode;
// 初始化快慢指针
fastNode = node;
slowNode = node;
while (fastNode != null && fastNode.getNextNode() != null) {
// fast指针每次前进2步
fastNode = fastNode.getNextNode().getNextNode();
// slow指针每次前进1步
slowNode = slowNode.getNextNode();
if (fastNode == slowNode) {
return true;
}
}
return false;
}
/**
* 判断链表是否相交
*/
public boolean isBanana(LinkedListNode node1, LinkedListNode node2) {
// 首先判断链表是否存在环
boolean isLoop1 = isLoop(node1);
boolean isLoop2 = isLoop(node2);
if (isLoop1) {
System.out.println("链表1存在环");
}
if (isLoop2) {
System.out.println("链表2存在环");
}
// 只有当两者都不存在环或者都存在环才有相交的可能性。
List<Integer> hashList = new ArrayList<Integer>();
if (isLoop1 == isLoop2) {
// 遍历第一个链表
while (node1 != null) {
hashList.add(node1.hashCode());
node1 = node1.getNextNode();
}
while (node2 != null) {
if (hashList.contains(node2.hashCode())) {
System.out.println("链表相交");
bananaNode = node2;
return true;
}
node2 = node2.getNextNode();
}
}
return false;
}
public static void main(String[] args) {
}
}
相关文章推荐
- 算法与数据结构面试题(1)-把二元查找树转变成排序的双向链表
- 算法与数据结构面试题(13)-求链表倒数第K个节点
- 转:链表相交有环 经典面试题(三)附答案 算法+数据结构+代码 微软Microsoft、谷歌Google、百度、腾讯
- 左程云_算法与数据结构 — 链表问题 — Node、DoubleNode、RandomNode类
- 算法与数据结构面试题(10)-颠倒链表
- 左程云_算法与数据结构 — 链表问题 — 04反转单向和双向链表
- 算法与数据结构基础系列(一): 链表的常见问题分析及实现
- 线性表11|单链表小结:腾讯面试题 - 数据结构和算法16
- 算法与数据结构面试题(11)-一次遍历得到链表的中间节点
- 左程云_算法与数据结构 — 链表问题 — 02在单链表和双链表中删除倒数第K个节点
- 左程云_算法与数据结构 — 链表问题 — 03删除链表的中间节点和a/b处的节点
- 左程云_算法与数据结构 — 链表问题 — 01打印两个有序链表的公共部分
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- 《算法大全-面试题-链表-栈-二叉树-数据结构》
- 线性表11|单链表小结:腾讯面试题 - 数据结构和算法16
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- 左程云_算法与数据结构 — 链表问题 — 05反转部分单链表
- 算法大全(1)单链表 http://rrurl.cn/f1Re2j 本文所有13道算法题目,覆盖了基本上所有常见的单链表问题
- 面试题之链表问题 - 找出倒数第k个元素(或中间元素)
- 数据结构之链表与数组(二) -单向链表上的简单操作问题