1. 定义单链表的数据结构类-Node
//定义vlue
public int value;
//定义当前节点的下一个节点
public Node next;
public Node(int val) {
this.value = val;
}
2 测试Main函数
public static void main(String[] args) {
Node node = new Node(1);
node.next = new Node(2);
node.next.next = new Node(3);
node.next.next.next = new Node(4);
node.next.next.next.next = new Node(5);
node.next.next.next.next.next = new Node(6);
node.next.next.next.next.next.next = new Node(7);
// node.next.next.next.next.next.next.next = node.next.next.next;
Node node2 = new Node(11);
node2.next = new Node(12);
node2.next.next = new Node(13);
node2.next.next.next = new Node(14);
node2.next.next.next.next = new Node(15);
node2.next.next.next.next.next = new Node(16);
// node2.next.next.next.next.next.next = node.next.next.next.next.next.next;
// node2.next.next.next.next.next.next = node2.next.next;
node2.next.next.next.next.next.next = node.next.next;
Node restNode = getInstersectNode(node, node2);
System.out.println(restNode.value);
}
3. 查找两个链表是否有环,是否相交,并返回相交的第一个节点入口函数
//查找两个链表是否有环,是否相交,并返回相交的第一个节点
public static Node getInstersectNode(Node node1, Node node2) {
Node loopNode1 = findLoop(node1);
Node loopNode2 = findLoop(node2);
if (loopNode1 != null && loopNode2 != null) {
return bothLoopNode(node1, loopNode1, node2, loopNode2);
}
if (loopNode1 == null && loopNode2 == null) {
return noLoopNode(node1, node2);
}
return null;
}
4. 两个链表不成环,获取相交的节点函数
public static Node noLoopNode(Node node1, Node node2) {
if (node1 == null || node2 == null) {
return null;
}
//定义两个变量
Node cur1 = node1;
Node cur2 = node2;
int count = 0;
//让cur1先迭代循环,并对count++
while (cur1 != null) {
count++;
cur1 = cur1.next;
}
//让cur2迭代循环,并对count--
while (cur2 != null) {
cur2 = cur2.next;
count--;
}
//cur1和cur2都走到了最后,判断二者是否相等,如果不相等说明二者没有相交
if (cur1 != cur2) {
return null;
}
//对cur1和cur2 重新 赋值,
//cur1是长链表,反之短链表
cur1 = count > 0 ? node1 : node2;
cur2 = cur1 == node1 ? node2 : node1;
count = Math.abs(count);
//长链表先走
while (count != 0) {
cur1 = cur1.next;
count--;
}
//cur1和cur2一起走
//找到二者相交的第一个节点
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
}
5. 两个链表都成环获取相交的第一个节点(两种情况)
第一种:成环节点一样,说明相交节点在成环前面
第二种:成环节点不一样,说明相交节点在环内
/**
* 两个链表都成环,判断是否相交
* 如果相交返回第一个节点
*/
public static Node bothLoopNode(Node node1, Node loopNode1, Node node2, Node loopNode2) {
//两个链表都成环并且成环的节点都一样,说明二者是相交
if (loopNode1 == loopNode2) {
Node cur1 = node1;
Node cur2 = node2;
int count = 0;
//计算到node1 头节点到成环节点的个数
while (cur1 != loopNode1) {
count++;
cur1 = cur1.next;
}
//计算到node2 头节点到成环节点的个数
while (cur2 != loopNode2) {
count--;
cur2 = cur2.next;
}
//重新制定cur1和cur2 ,cur1 为长链表
cur1 = count > 0 ? node1 : node2;
cur2 = cur1 == node1 ? node2 : node1;
count = Math.abs(count);
//长链表先走多出来的节点
while (count != 0) {
cur1 = cur1.next;
count--;
}
//找到两个链表的相交点,相交的点一定一样,
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
} else {
Node cur1 = loopNode1.next;
while (cur1 != loopNode1) {
if (cur1 == loopNode2) {
return cur1;
}
cur1 = cur1.next;
}
}
return null;
}