剑指Offer——两个链表的第一个公共结点

题目:输入两个链表,找出它们的第一个公共结点。

思路一:

1、先求出两个链表的长度差gap,让比较长的链表先向前遍历gap个节点,然后两个链表同时向前遍历,直到遇到相同的节点为止。时间复杂度:O(m+n);m和n分别为两个链表的长度。

/**
     * 解法一:求得两个链表的长度差d,让较长的链表先走d步,然后两个链表再一起遍历,时间复杂度O(m+n)
     * @param pHead1
     * @param pHead2
     * @return
     */
    public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null||pHead2==null){
            return null;
        }
        ListNode p1=pHead1;
        ListNode p2=pHead2;
        int p1Length=0;
        int p2Length=0;

        while (p1!=null){
            p1Length++;
            p1=p1.next;
        }
        while (p2!=null){
            p2Length++;
            p2=p2.next;
        }

        if(p1Length>p2Length){
            p1=walkStep(pHead1,p1Length-p2Length);
            p2=pHead2;
        }else{
            p1=pHead1;
            p2=walkStep(pHead2,p2Length-p1Length);
        }
        while (p1!=null){
            if(p1==p2) return p1;
            p1=p1.next;
            p2=p2.next;
        }
        return null;

    }

    public static ListNode walkStep(ListNode pHead, int step){
        while(step>0){
            pHead = pHead.next;
            step--;
        }
        return pHead;
    }

    public static void main(String [] args){
        ListNode b1 = new ListNode(1);
        ListNode b2 = new ListNode(2);
        ListNode b3 = new ListNode(3);
        ListNode b4 = new ListNode(4);
        ListNode b5 = new ListNode(5);
        ListNode b6 = new ListNode(6);
        ListNode b7 = new ListNode(7);

        b1.next = b2;
        b2.next = b3;
        b3.next = b6;
        b6.next = b7;
        b4.next = b5;
        b5.next = b6;
        ListNode a=FindFirstCommonNode(b1,b4);
        System.out.println(a);
    }

思路二:如下图;将链表分为两部分,则两个链表的长度分别为a+c,b+c;得到a+c+b=b+c+a(即链表A遍历结束后从链表B开始遍历,链表B遍历结束后从链表A开始遍历,当两个链表的指针相遇时,就是第一个公共结点)

代码:

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    ListNode l1 = pHead1, l2 = pHead2;
    while (l1 != l2) {
        l1 = (l1 == null) ? pHead2 : l1.next;
        l2 = (l2 == null) ? pHead1 : l2.next;
    }
    return l1;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值