剑指offer--两个链表的第一个公共结点(Java)

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

  1. 蛮力法:遍历第一个链表的结点,每到一个结点,就在第二个链表上遍历每个结点,判断是否相等。时间复杂度为O(m*n),效率低,注意新一轮循环要将链表指向头部
  2. 使用栈:由于公共结点出现在尾部,所以用两个栈分别放入两个链表中的结点,从尾结点开始出栈比较。时间复杂度O(m+n),空间复杂度O(m+n)。
  3. 利用长度关系:计算两个链表的长度之差,长链表先走相差的步数,之后长短链表同时遍历,找到的第一个相同的结点就是第一个公共结点。

实现:

//蛮力法
    public ListNode FindFirstCommonNode1(ListNode pHead1, ListNode pHead2) {
        ListNode init = pHead2;
        while(pHead1!=null){
            while(pHead2!=null) {
                System.out.println(pHead1.val+" "+pHead2.val);
                if(pHead1 == pHead2) {
                    System.out.println("yes");
                    return pHead1;
                }
                pHead2 = pHead2.next;
            }
            pHead1 = pHead1.next;
            pHead2 = init;
        }
        return null;
    }
    //栈
    public ListNode FindFirstCommonNode2(ListNode pHead1, ListNode pHead2) {
        Stack<ListNode> s1 = new Stack<>();
        Stack<ListNode> s2 = new Stack<>();
        while(pHead1!=null){
            s1.push(pHead1);
            pHead1 = pHead1.next;
        }
        while(pHead2!=null){
            s2.push(pHead2);
            pHead2 = pHead2.next;
        }
        ListNode res = null;
        while(s1.size()!=0&&s2.size()!=0&&s1.peek() == s2.peek()){
            res = s1.peek();
            s1.pop();
            s2.pop();
        }
        return res;
    }
    //长度关系
    public ListNode FindFirstCommonNode3(ListNode pHead1, ListNode pHead2) {
        int len1 = getLen(pHead1);
        int len2 = getLen(pHead2);
        ListNode longList = pHead1;
        ListNode shortList = pHead2;
        int pre = len1 -len2;
        if(len1<len2){
            longList = pHead2;
            shortList = pHead1;
            pre = len2 -len1;
        }
        while((pre--)>0){
            longList =longList.next;
        }
        while(longList!=null&&shortList!=null&&longList!=shortList){
            longList=longList.next;
            shortList=shortList.next;
        }
        return longList;
    }
    public int getLen(ListNode head){
        int len=0;
        while(head!=null){
            len++;
            head = head.next;
        }
        return len;
    }

收获:

由于有共同结点时,后面的链表是重合的,所以这道题关键是要保证最后同时遍历到达尾结点,因此就有了后面的方法:
利用栈的先进后出实现同时到达;
利用长度关系,长链表先行几步,实现同时到达;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值