问题:寻找两个单项链表的交点。
一、输入输出。
输入:两个带空头结点的单向链表
输出:如果有相交的节点,输出节点值;如果没有,打印“没有找到相交节点”。
= =。好吧回头看了一下好像这个方法是错的。。。。。。
二、解题原理
这题原理很简单,首先是遍历两个链表,获取它们的长度;然后求出它们的长度差(difference),让长的一个链表先前进difference的距离,也就是说此时两个链表剩下的元素值个数相等。接着两个链表都一步一步前进,如果发现某处有相同节点,则这个就是相交节点,反之两个节点分别前进到末端,返回Null。
三、代码实现(JAVA)
1.首先这是一个定义的节点。
class Node<T>{
public Node next;
public T data;
public Node(){
data = null;
next = null;
}
public Node(T data, Node<T> next){
this.data = data;
this.next = next;
}
}
2.然后这里是我们主要的查找算法。
//查找两个单向链表的相交节点
public static Node findTheCrossNode(Node lhs, Node rhs){
int len_lhs = 0;
int len_rhs = 0;
Node tlhs = lhs;
Node trhs = rhs;
//计算链表一长度
while (tlhs.next != null){
len_lhs++;
tlhs = tlhs.next;
}
//计算链表二长度
while (trhs.next != null){
len_rhs++;
trhs = trhs.next;
}
//计算两个链表的长度差
int difference = Math.abs(len_lhs - len_rhs);
//先让长的一个链表走步长为difference的距离
//然后开始两个链表同步向前,如果有相交节点则会找到相同节点
//否则两个链表都到最后null
if(len_lhs > len_rhs){
for (int i = 0; i < difference; i++)
lhs = lhs.next;
}
else {
for (int i = 0; i < difference; i++)
rhs = rhs.next;
}
while(lhs != rhs){
System.out.println("node1 = " + lhs.data + " node2 = " + rhs.data);
lhs = lhs.next;
rhs = rhs.next;
}
return lhs;
}
3.然后通过Main函数进行了测试,验证成功哈哈哈哈哈哈哈。在例子特地设置了相交节点值为2。
public static void main(String[] args) {
//两个单项链表为带空头结点的链表
Node<Integer> list1 = new Node<>(-1, null);
Node<Integer> list2 = new Node<>(-1, null);
Node cross = null;
Node lastNode = list1;
//构建链表一, 0->1->2->3->4
for (int i = 0; i < 5; i++){
lastNode.next = new Node<>(i, null);
if (i == 2) //相交节点为4
cross = lastNode.next;
lastNode = lastNode.next;
}
//构建链表二, 10->9->8->2->3->4
lastNode = list2;
for (int i = 10; i > 7; i--){
lastNode.next = new Node<>(i, null);
lastNode = lastNode.next;
}
lastNode.next = cross;
cross = findTheCrossNode(list1, list2);
if (cross != null)
System.out.println("相交节点值为: " + cross.data);
else
System.out.println("没有相交节点");
}
4.输出结果如下
node1 = -1 node2 = 10
node1 = 0 node2 = 9
node1 = 1 node2 = 8
相交节点值为: 2
扩展问题
问题:如何判断一个单链表有环?
提示:用两个指针,一个每次递增一步,另一个每次递增两步,如果有环两个必重合,反之亦然。