LeetCode.160.相交链表

编写一个程序,找到两个单链表相交的起始节点。
LeetCode-160.相交链表
思路:
1.如果headA或headB为空 则无交点
2.设定两个指针a和b,a从headA(a1)开始,b从headB(b1)开始
3.两者同时后移,若a移到headA链表尾(c3)则a换路从headB(b1)开始接着后移;若b移到headB链表尾(c3)则b换路从headA(a1)开始接着后移
4.后移过程中,若出现a和b指向同一节点,则该节点为交点;若a和b皆换路且都到达链表尾部,则无交点
原理
虽然题目中强调了链表中不存在环,但是我们可以用环的思想来做,我们让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况,一种情况是在交点处相遇,另一种情况是在各自的末尾的空节点处相等。为什么一定会相等呢,因为两个指针走过的路程相同,是两个链表的长度之和,所以一定会相等。这个思路比较巧妙,而且更重要的是代码写起来特别的简洁。
难点
因为按照换路思想两个指针遍历的总路程相等,所以换路后两个指针对应元素最终肯定会相等,相等有两种情况:1、两个指针在交点处相遇所指的元素对应相等,此时返回一个元素值;2、若无交点,两个指针最终都指向空(此情况也算是相等),此时返回null;
解法1

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null) return null;   //先判空
        ListNode a=headA;   //A链表第一个元素给a
        ListNode b=headB;
        while(a!=b){        //在a不等于b的情况下
            a=(a!=null)?a.next:headB;   //利用三目运算符,若当前a不为空时a=a.next否则换路
            b=(b!=null)?b.next:headA;
        }
        return a;       //如果a=b时,返回a/b都行
    }
}

解法2

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null) return null;   //先判空
        ListNode pa=headA;   //A链表第一个元素给a
        ListNode pb=headB;
        boolean ispachange=false;   //给定换路标记,默认为false
        boolean ispbchange=false;
        while(pa!=null&&pb!=null){
            if(pa==pb){
                return pa;
            }
            pa=pa.next;
            pb=pb.next;
            if(ispachange&&ispbchange&&pa==null&&pb==null){ //如果换路了并且到达尾部则说明没有相交
                break;
            }
            if(pa==null){   
                pa=headB;   //如果pa指向空则换路
                ispachange=true;    //标记换路
            }
            if(pb==null){
                pb=headA;
                ispbchange=true;
            }
        }
        return null;    
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44561640/article/details/88809131