JAVA OJ练习第9题——相交链表

力扣链接:160.相交链表

编写一个程序,找到两个单链表相交的起始节点。

示例:
如下面的两个链表:

在这里插入图片描述

在节点 c1 开始相交。

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8

方法一:

思路如下:

判断两个单链表是否相交。当两链表地址一样的时候即相交。

判断的依据:地址一样,是Y类交叉。

难点就在于两链表的长度不一样,所以要先求二者长度的差值,让长的单链表先走,在判断即可。

代码如下:

public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;   //此时没有交点
        }

        ListNode pL = headA;//永远指向长的单链表
        ListNode pS = headB;//永远指向短的单链表

        int lenA = 0;
        int lenB = 0;
		//求各链表的长度
        //求的lenA  lenB
        while (pL != null) {
            lenA++;
            pL = pL.next;
        }
        while (pS != null) {
            lenB++;
            pS = pS.next;
        }
        pL = headA;
        pS = headB;
        //差值-》最长的单链表先走len步
        int len = lenA - lenB;
        if (len < 0) {
            pL = headB;
            pS = headA;
            len = lenB - lenA;
        }

        //让pL先走len步
        while (len > 0) {
            pL = pL.next;
            len--;
        }
        //开始一起走  (pL  != pS ) {一人一步走}
        while (pL != pS) {
            pS = pS.next;
            pL = pL.next;
        }
        if ( pL == null ){
            return null;
        }
        return pL;   //return pS;
    }
    public static void createCut    //相交的链表
            (ListNode headA, ListNode headB) {
        headA.next = headB.next.next;
    }

测试:

public static void main(String[] args) {
        SingleList singleList = new SingleList();
        SingleList singleList2 = new SingleList();
        
        singleList.addLast(1);
        singleList.addLast(2);
        singleList.addLast(3);
        singleList.addLast(10);
        singleList.display();
        
        singleList2.addLast(3);
        singleList2.addLast(4);
        singleList2.addLast(10);
        singleList2.addLast(17);
        singleList2.display();
        
        createCut(singleList.head,singleList2.head);
        
        ListNode node = getIntersectionNode(singleList.head,singleList2.head);
        
        System.out.println(node.data);
}

//结果为
1 2 3 10
3 4 10 17
10

方法二:

上述方法虽然简单易懂,但有些冗余,急性子的人怕是很难静心看完,来看下一个方法:

思路:
定义两个指针, 第一轮让两个到达末尾的节点指向另一个链表的头部, 最后如果相遇则为交点(在第一轮移动中恰好抹除了长度差);两个指针等于移动了相同的距离, 有交点就返回, 无交点就是各走了两条指针的长度
在这里第一轮体现在pA和pB第一次到达尾部会移向另一链表的表头, 而第二轮体现在如果pA或pB相交就返回交点, 不相交最后就是null。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
         /**
        定义两个指针, 第一轮让两个到达末尾的节点指向另一个链表的头部, 
        最后如果相遇则为交点(在第一轮移动中恰好抹除了长度差)
        
        两个指针等于移动了相同的距离, 有交点就返回, 
        无交点就是各走了两条指针的长度
        **/
        if(headA == null || headB == null) return null;
        ListNode pA = headA, pB = headB;
        /* 在这里第一轮体现在pA和pB第一次到达尾部会移向另一链表的表头, 
        而第二轮体现在如果pA或pB相交就返回交点, 不相交最后就是null == null*/
        while(pA != pB) {
            pA = pA == null ? headB : pA.next;
            pB = pB == null ? headA : pB.next;
        }
        return pA;
    }
}

当然了,第二个方法虽然代码少,但还是需要自己仔细研究搞懂,否则还是第一种方法更靠谱一些。


下一题:环形链表
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值