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

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

方法一:两个单链表有公共节点,也就是说两个链表从某一个节点开始,next域都指向同一个节点,由于每个单链表节点只有一个Next域,因此从第一个公共节点开始,之后所有的节点都是重合的,不可能再出现分叉,所以,两个有公共节点而部分重合的单链表,形状看起来Y。 所以只要分别遍历两个链表到最后一个节点。如果两个尾节点是一样的,说明它们有公共节点,否则两个链表没有公共的节点。假设一个链表比另一个长K个节点,我们在长的链表上遍历K个节点,之后再同步遍历,此时我们就能保证同时到达最后一个节点。 分别遍历两个链表得到它们的长度,并求出两个长度差。在长的链表上先遍历长度之差的节点之后,再同步遍历两个链表,直到找到相同的节点。

 public ListNode FindFirstCommonNode1(ListNode pHead1, ListNode pHead2) {
        int len1=length(pHead1);
        int len2=length(pHead2);
        int dist;
        ListNode langList;
        ListNode shortList;
        if(len1>len2)
        {
            langList=pHead1;
            shortList=pHead2;
            dist=len1-len2;
        }
        else {
            langList=pHead2;
            shortList=pHead1;
            dist=len1-len2;
            dist=len2-len1;
        }
        for(int i=0;i<dist;i++){
            langList=langList.next;
        }
      while(langList!=null){
          if(langList==shortList)
          {
              return langList;
          }
          else{
              langList=langList.next;
              shortList=shortList.next;
          }
      }
        return null;
    }

    public int length(ListNode listNode)
    {
        if(listNode==null){
            return 0;
        }
        int count=0;
        while(listNode!=null)
        {
            ++count;
            listNode=listNode.next;
        }
        return count;
    }

方法二:如果两个链表有公共结点,那么公共结点出现在两个链表的尾部。如果我们从两个链表的尾部开始向前比较,那么最后一个相同的节点就是要找的节点。在这个基础上想到了使用栈。分别把两个链表的节点放在两个栈里,这样两个链表的尾节点就位于两个栈的栈顶,接下来比较两个栈顶的时间是否相同,如果相同,则把栈顶弹出接着比较下一个栈顶,直到找到最后一个相同的节结点。

 public ListNode FindFirstCommonNode2(ListNode pHead1, ListNode pHead2){
        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;
        }
        //peek返回栈顶的值,不会删除栈顶
        ListNode Node = null;
        while(!stack1.isEmpty() && !stack2.isEmpty() && stack1.peek()==stack2.peek()){
            stack2.pop();
            Node = stack1.pop();;
        }
        return Node;

    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值