力扣简160 相交链表 *

SET + 双指针 类似于141龟兔赛跑双指针

三元操作符需要将结果赋值给一个变量的

a.equals(b) 要求a b不为空,否则抛出异常
a==b 可以接受为空


有相同元素时常用set,利用set中不可能有相同元素的特性。
//最开始的思路,找出两个中较短的一个,与另一个长的相互对其末尾比较对应部分是否相等,
//这种情况只考虑了长的后半部分和短的完全重合,都没有想两者开头不重合,但是后半部分重合这种情况。错误!想不到啥好办法。
package leetcode01;

import java.awt.List;

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
//给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

public class Solution160 {
    //最开始的思路,找出两个中较短的一个,与另一个长的相互对其末尾比较对应部分是否相等,
    //这种情况只考虑了长的后半部分和短的完全重合,都没有想两者后半部分重合这种情况。错误!想不到啥好办法。
    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode res=null;
        ListNode head=headA;
        while(head!=null) {
            if(head.equals(headB)) {
                return head;
            }
            head=head.next;
        }
        head=headB;
        while(head!=null) {
            if(head.equals(headA)) {
                return head;
            }
            head=head.next;
        }
        return res ;
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ListNode mul=new ListNode(8,new ListNode(4,new ListNode(5)));
        
        ListNode headA=new ListNode(4,new ListNode(1,mul));
        ListNode headB=new ListNode(5,new ListNode(6,new ListNode(1,mul)));
        ListNode res=getIntersectionNode(headA,headB);
        System.out.print(res);
    }

}

 

题解1:巧用set

    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> set=new HashSet<ListNode>();
        ListNode tempA=headA;
        while(tempA!=null) {
            set.add(tempA);
            tempA=tempA.next;
        }
        ListNode tempB=headB;
        while(tempB!=null) {
            if(set.contains(tempB)) {
                return tempB;//存着树的节点,自然就有next可以查找。
            }    
            tempB=tempB.next;
        }
        return null;
    }

 

题解二:双指针

    本来是这样的逻辑
    if(pb!=null) {
        pb=pb.next;
        continue;//不加此句会导致在一次判断中刚置next为空紧接着就又因为空移动一次指针。 
    }    
    if(pb==null) {
        pb=headA;
    }
又想到可以先处理空情况,再处理非空。省代码量!
改了改发现不可以!如果把判空放在前面,置为另一链表的头的时候又不为空执行两次了!
如果pa为空,执行一次continue,那么指针pb的移动会被跳过,所以也不多!其实换成else if就能解决!
//题解二:双指针
    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null)
            return null;
        ListNode pa=headA;
        ListNode pb=headB;
        while(pa!=null||pb!=null) {
            if(pa!=null&&pb!=null&&pa.equals(pb)) {//若不加判空会抛出异常。 若直接用pa==pb,可以接受其中一方为空。
                return pa;
            }
            if(pa!=null) {
                pa=pa.next;
            }
            else if(pa==null){
                pa=headB;
            }
            if(pb!=null) {
                pb=pb.next;
            }    
            else if(pb==null) {
                pb=headA;
            }
        }    
        return null;    
    }

自己对于题解二的优化,运用了三元运算符

public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null)
            return null;
        ListNode pa=headA;
        ListNode pb=headB;
        while(pa!=null||pb!=null) {
            if(pa!=null&&pb!=null&&pa.equals(pb)) {
                return pa;
            }
            pa=(pa==null)?headB:pa.next;
            pb=(pb==null)?headA:pb.next;
        }    
        return null;    
    }

官方题解二:确实简洁!!

//官方题解二
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }
        ListNode pA = headA, pB = headB;
        while (pA != pB) {
            pA = pA == null ? headB : pA.next;
            pB = pB == null ? headA : pB.next;
        }
        return pA;
    }

 

posted @ 2022-05-28 17:03  Ssshiny  阅读(26)  评论(0)    收藏  举报