算法:寻找无环或者有环的2个单向链表的相交节点
// 获取相交节点
public static Node getNode(Node head1, Node head2) {
if (head1 == null || head2 == null) {
return null;
}
// 获取第一个链表的入环节点
Node loop1 = getLoopNode(head1);
// 获取第二个链表的入环节点
Node loop2 = getLoopNode(head2);
// 如果2个为空,则代表2个链表均无环
if (loop1 == null && loop2 == null) {
return noLoop(head1, head2);
}
// 如果均有环
if (loop1 != null && loop2 != null) {
return bothLoop(head1, loop1, head2, loop2);
}
return null;
}
// 获取无环的2个链表的相交节点
public static Node noLoop(Node head1, Node head2) {
int len1 = 0;
int len2 = 0;
Node n1 = head1;
Node n2 = head2;
// 获取第一个链表的长度
while (n1.next != null) {
len1++;
n1 = n1.next;
}
// 获取第二个链表的长度
while (n2.next != null) {
len2++;
n2 = n2.next;
}
// 如果尾部节点不一致,则2个链表无公共部分
if (n1 != n2) {
return null;
}
// 求2个长度的差值
int c = Math.abs(len1 - len2);
// 找到最长的链表
Node h = len1 > len2 ? head1 : head2;
// 最短的链表
Node h2 = len1 > len2 ? head2 : head1;
// 让最长的链表多走c步,使2个链表的长度一致
while (c > 0) {
h = h.next;
c--;
}
// 2个链表同时遍历,直到相等节点,则为相交节点
while (h != h2) {
h = h.next;
h2 = h2.next;
}
return h;
}
public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
if (loop1 == loop2) {
int len1 = 0;
int len2 = 0;
Node n1 = head1;
Node n2 = head2;
while (n1 != loop1) {
len1++;
n1 = n1.next;
}
while (n2 != loop1) {
len2++;
n2 = n2.next;
}
// 如果尾部节点不一致,则2个链表无公共部分
if (n1 != n2) {
return null;
}
int c = Math.abs(len1 - len2);
Node h = len1 > len2 ? head1 : head2;
Node h2 = len1 > len2 ? head2 : head1;
while (c > 0) {
h = h.next;
c--;
}
while (h != h2) {
h = h.next;
h2 = h2.next;
}
return h;
} else {
Node cur = loop1.next;
while (cur != loop1) {
if (cur == loop2) {
return loop1;
}
cur = cur.next;
}
return null;
}
}
public static Node getLoopNode(Node head) {
if (head == null || head.next == null) {
return null;
}
// 快慢指针,快指针一定会遇到慢指针
Node n1 = head.next;
Node n2 = head.next.next;
while (n2 != null && n2.next != null) {
if (n1 == n2) {
break;
}
n1 = n1.next;
n2 = n2.next.next;
}
// 将快指针重置到头节点,慢指针保留原地,2个指针同时走,一定会在入环节点相遇
n2 = head;
while (n1 != null && n2 != null) {
if (n1 == n2) {
break;
}
n1 = n1.next;
n2 = n2.next;
}
return n1;
}
作者:言小溪enncy
出处:https://www.cnblogs.com/enncy/p/16166553.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具