链表相交问题(双指针法)(java和c语言)
双指针法是一种高效且优雅的解决链表相交问题的方法。通过让两个指针分别遍历两个链表,并在到达末尾时切换到另一个链表,我们可以在不额外占用空间的情况下找到相交的起始节点。希望这篇博客能帮助你理解这一方法,并在实际编码中应用它。
·
问题描述
给你两个单链表的头节点 headA 和 headB,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null。
方法:双指针
一种高效的方法是使用两个指针,分别从两个链表的头部开始遍历。当一个指针到达链表末尾时,它切换到另一个链表的头部继续遍历。如果两个链表相交,那么这两个指针一定会在某一点相遇,这个相遇点就是相交的起始节点。
实现思路
- 初始化两个指针:分别指向链表A和链表B的头节点。
- 遍历链表:每次移动一步。
- 切换链表:当一个指针到达链表末尾时,将其指向另一个链表的头节点。
- 寻找相遇点:继续遍历,直到两个指针相遇。相遇点即为相交的起始节点。
这种方法巧妙地利用了双指针,避免了额外的空间开销,时间复杂度为O(m + n),其中m和n分别是两个链表的长度。
代码实现(Java)
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode tempA = headA;
ListNode tempB = headB;
while (tempA != tempB) {
tempA = tempA == null ? headB : tempA.next;
tempB = tempB == null ? headA : tempB.next;
}
return tempA;
}
}
代码实现(C)
#include <stdlib.h>
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if (headA == NULL || headB == NULL) return NULL;
struct ListNode *tempA = headA;
struct ListNode *tempB = headB;
while (tempA != tempB) {
tempA = tempA == NULL ? headB : tempA->next;
tempB = tempB == NULL ? headA : tempB->next;
}
return tempA;
}
为什么这种方法有效?
假设链表A的长度为a + c,链表B的长度为b + c,其中c是相交的部分。
- 如果a = b,那么两个指针会同时到达相交点。
- 如果a ≠ b,指针A会先遍历完链表A,然后切换到链表B,指针B会先遍历完链表B,然后切换到链表A。这样,它们总共遍历的长度都是a + b + c,因此会在相交点相遇。
如果没有相交点,两个指针最终都会同时到达链表末尾,即NULL,从而结束循环并返回NULL。
总结
双指针法是一种高效且优雅的解决链表相交问题的方法。通过让两个指针分别遍历两个链表,并在到达末尾时切换到另一个链表,我们可以在不额外占用空间的情况下找到相交的起始节点。希望这篇博客能帮助你理解这一方法,并在实际编码中应用它。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)