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

package com.niuke;

import java.util.HashMap;
import java.util.Stack;

/**
 * Created by admin on 2018/3/11.
 * 输入两个链表,找出它们的第一个公共结点。
 public class ListNode {
 int val;
 ListNode next = null;

 ListNode(int val) {
 this.val = val;
 }
 */
public class FindFirstCommonNode {//比较地址
    //不需比较长度找出2个链表的长度
    //1 用两个指针扫描”两个链表“,最终两个指针到达 null 或者到达公共结点。
    public ListNode findFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode p1=pHead1;
        ListNode p2=pHead2;
        while(p1!=p2) {
            p1=(p1==null?pHead2:p1.next);
            p2=(p2==null?pHead1:p2.next);
        }
        return p1;
        //假定 List1长度: a+n  List2 长度:b+n, 且 a<b那么 p1 会先到链表尾部,
        // 这时p2 走到 a+n位置,将p1换成List2头部接着p2 再走b+n-(n+a) =b-a 步到链表尾部,
        // 这时p1也走到List2的b-a位置,还差a步就到可能的第一个公共节点。
        // 将p2 换成 List1头部,p2走a步也到可能的第一个公共节点。
        // 如果恰好p1==p2,那么p1就是第一个公共节点。或者p1和p2一起走n步到达列表尾部,二
        // 者没有公共节点,退出循环。同理a>=b.时间复杂度O(n+a+b)
    }

    //找出2个链表的长度,然后让长的先走两个链表的长度差,然后再一起走(因为2个链表用公共的尾部)
    public ListNode FindFirstCommonNode2(ListNode pHead1, ListNode pHead2) {
        int len1=getListLen(pHead1);//求链表pHead1的长度
        int len2=getListLen(pHead2);//求链表pHead2的长度
        if(pHead1==null||pHead2==null) {
            return null;
        }
        if(len1>len2) {//链表pHead1的长度大于链表pHead2的长度
            int len=len1-len2;//长度差
            while(len>0) {
                pHead1=pHead1.next;
                len--;
            }
        }
        if(len2>len1) {//链表pHead2的长度大于链表pHead1的长度
            int len=len2-len1;//长度差
            while(len>0) {
                pHead2=pHead2.next;
                len--;
            }
        }
        //开始齐头并进直到找到公共节点
        while(pHead1!=pHead2) {
            pHead1=pHead1.next;
            pHead2=pHead2.next;
        }
        return pHead1;
    }

    public int getListLen(ListNode head) {//求链表的长度
        int count=0;
        while(head!=null) {
            head=head.next;
            count++;
        }
        return count;
    }

    //3运用HashMap的特性
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        HashMap<ListNode,Integer> hashMap=new HashMap<>();
        while(pHead1!=null) {
            hashMap.put(pHead1,null);
            pHead1=pHead1.next;
        }

        while(pHead2!=null) {
           if(hashMap.containsKey(pHead2)) {
               return pHead2;
           }
           pHead2=pHead2.next;
        }
        return null;
    }

    //4 两个链表从尾部往前到某个点,节点都是一样的。
    // 我们可以用两个栈分别来装这两条链表。一个一个比较出来的值。
    public ListNode FindFirstCommonNode4(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null||pHead2==null) {
            return null;
        }
        Stack<ListNode> stack1=new Stack<>();
        Stack<ListNode> stack2=new Stack<>();
        //将两个链表分别压入两个栈中
        while (pHead1!=null) {
            stack1.push(pHead1);
            pHead1=pHead1.next;
        }

        while (pHead2!=null) {
            stack2.push(pHead2);
            pHead2=pHead2.next;
        }

        ListNode result=null;
        while(!stack1.isEmpty()&&!stack2.isEmpty()&&stack1.peek()==stack2.peek()) {
            stack1.pop();
            result=stack2.pop();
        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值