题目描述
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
1:双指针
解题思路
先求得两个链表的长度差,假设长度差为2,那就让比较长的链表的头结点先走2个节点,然后两条链表的头结点一起走,他们会同时走到相交节点。
代码展示
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode tempA=headA;
ListNode tempB=headB;
int lenA=0,lenB=0;
while(tempA!=null)//求A链表的长度
{
lenA++;
tempA=tempA.next;
}
while(tempB!=null)//求B链表的长度
{
lenB++;
tempB=tempB.next;
}
int diff=0;//两链表的长度差
// lenA>=lenB?return getNode(headA, headB, diff):
if( lenA>=lenB)
{
diff=lenA-lenB;
return getNode(headA, headB, diff);
}
else
{
diff=lenB-lenA;
return getNode(headB, headA, diff);
}
}
public ListNode getNode(ListNode headA, ListNode headB,int diff)
{
//默认传进来的参数,第一个链表的长度len1大于第二个链表的长度len2
while(diff>0&&headA!=null)//先让长一点的链表走diff步
{
headA=headA.next;
diff--;//走一步减一个
}
while(headA!=headB&&headA!=null)//此时,headA和headB距离相交节点长度一样
{
headA=headA.next;
headB=headB.next;
}
return headA;
}
}
双指针参考解法(稳的一批)
总结:相遇时,两个指针走的路程一样,A:a+(b-c),B:b+(a-c),当A走了a+(b-c)时,正好到达相交节点,当B走了b+(a-c)时,正好到达相交节点,所以此时两个链表的头指针都在相交节点
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA, B = headB;
while (A != B) {
A = A != null ? A.next : headB;
B = B != null ? B.next : headA;
}
return A;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/intersection-of-two-linked-lists-shuang-zhi-zhen-l/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析
2:哈希表
解题思路
把链表A先存进哈希表,每个节点就是一个对象,所以不用判断是否有重复,接下来把链表B的节点放进哈希表,此时就需要判断哈希表里面有没有对应的元素了,不过不用把B的节点存进哈希表,因为遍历到重复节点就可以直接返回该节点了,B里面的节点不可能跟B的节点重复,因为不同的节点是不同的对象,如果最后B遍历到了末尾,指向了null,说明链各个链表没有交点,返回null。
代码展示
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode>set=new HashSet<>();
while(headA!=null)
{
set.add(headA);
headA=headA.next;
}
while(headB!=null&&!set.contains(headB))
{
headB=headB.next;
}
if(headB==null)
{
return null;
}
else
{
return headB;
}
}
}
3:暴力法
牛皮:两个while…
代码展示
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode tempB= headB;//暂存头结点
while(headA!=null)
{
while(headB!=null)
{
if(headB!=headA)
{
headB=headB.next;
}
else
{
return headB;
}
}
headB=tempB;//内层while循环结束,恢复 headB为B的头结点
headA=headA.next;
}
return null;//如果在while循环里没有返回,说明没有交点,就返回null
}
}
bug总结
正解
int diff=lenA-lenB;//两链表的长度差
diff=Math.abs(diff);
总是忘记考虑head.next可能出现的空指针问题,应当考虑head!=null,再进行head=head.next操作