您的位置:首页 > 理论基础 > 数据结构算法

算法与数据结构面试题(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) {

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐