zoukankan      html  css  js  c++  java
  • 两个链表的第一个公共结点——牛客offer

    题目描述:

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

    题目分析:

    只是数据域相同不是公共节点。公共结点代表该节点在两个链表中的数据域和指针域都是相同的,这意味着从该公共节点开始,后面的结点都是两个链表共有的,如图:

    解题思路:

    思路1:

    从正序比较的角度来考虑:观察上图,链表1长度大于链表2,那么公共结点绝不可能存在于链表1比链表2多出来的那些结点中。基于这种想法,我们可以先求出两个链表的长度,然后现在长链表上遍历一段距离后,再开始同时遍历长链表和短链表并进行比较。

    思路2:

    从倒序比较的角度考虑:这个思路比较容易理解,因为两个链表的后面一部分是重复的,我们可以建立两个栈,将两个链表分别压入两个栈:

    此时如果有栈是空的,说明无公共节点,返回null;

    否则,循环取两个栈的栈顶元素进行比较:如果不相等,说明公共结点为该节点的下一个结点,否则循环直至有一个栈或两个栈为空终止:终止的原因有以下几条(1)如果两个栈都为空,说明是同一个链表,返回任意链表的头结点作为公共节点。例如{1,2,3} {1,2,3}(2)如果其中一个链表为空,说明短链表的全部元素都是和长链表共有的,则返回短链表的头结点。例如{1,2,3} {2,3}

    测试:两者性能差不多,运行时间和占用空间相差无几。

    代码实现:

    思路1

     1 public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
     2          Stack<ListNode> stack1=new Stack<ListNode>();
     3          Stack<ListNode> stack2=new Stack<ListNode>();
     4          ListNode walkNode=pHead1;
     5          while(walkNode!=null){
     6              stack1.push(walkNode);
     7              walkNode=walkNode.next;
     8          }
     9          walkNode=pHead2;
    10          while(walkNode!=null){
    11              stack2.push(walkNode);
    12              walkNode=walkNode.next;
    13          }
    14          //当两个链表都为空链表时,无公共结点,返回null
    15          if(stack1.size()==0||stack2.size()==0){
    16              return null;
    17          }
    18          while(!stack1.empty()&&!stack2.empty()){
    19              ListNode pop1=stack1.pop();
    20              ListNode pop2=stack2.pop();
    21              if(pop1!=pop2){
    22                  return pop1.next;
    23              } 
    24          }
    25          //当两个栈同时为空时,且没有出现非公共结点,说明两个链表是完全一样的
    26          if(stack1.size()==0&&stack2.size()==0){
    27              return pHead1;          //return pHead2;
    28          }
    29         //当stack1先空时,说明链表1的所有结点和链表2都是公共的
    30          else if(stack1.size()==0){
    31              return pHead1;
    32          }
    33         //当stack2先空时,说明链表2的所有结点和链表1都是公共的
    34          else{
    35              return pHead2;
    36          }
    37     }

    思路2

    获取链表长度:

    1 public static int getLength(ListNode pHead){
    2         ListNode walkNode=pHead;
    3         int length=0;
    4         while(walkNode!=null){
    5             length++;
    6             walkNode=walkNode.next;
    7         }
    8         return length;
    9 }

    寻找公共结点:

     1 public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
     2         int n1=getLength(pHead1);
     3         int n2=getLength(pHead2);
     4         int lenDiff=n1>n2?(n1-n2):(n2-n1);
     5         ListNode walkNode1=pHead1;
     6         ListNode walkNode2=pHead2;
     7         //将walkNode1与walkNode2对齐
     8         if(n1>n2){
     9             while(lenDiff>0){
    10                 lenDiff--;
    11                 walkNode1=walkNode1.next;
    12             }
    13         }
    14         else{
    15             while(lenDiff>0){
    16                 lenDiff--;
    17                 walkNode2=walkNode2.next;
    18             }
    19         }
    20         //遍历比较
    21         while(walkNode1!=null){
    22             if(walkNode1==walkNode2){
    23                 return walkNode1;
    24             }
    25             walkNode1=walkNode1.next;
    26             walkNode2=walkNode2.next;
    27         }
    28         return null;    
    29 }

    主函数测试:

    public static void main(String[]args){
            ListNode phead1=new ListNode(1);
            ListNode node11=new ListNode(2);
            ListNode node12=new ListNode(3);
        
            ListNode phead2=new ListNode(4);
            ListNode node21=new ListNode(5);
            
            ListNode node13=new ListNode(6);
            ListNode node14=new ListNode(7);
            
            phead1.next=node11;
            node11.next=node12;
            node12.next=node13;
            node13.next=node14;
            phead2.next=node21;
            node21.next=node13;
            node13.next=node14;
            System.out.print(FindFirstCommonNode(phead1,phead2).val);
    }
    View Code
  • 相关阅读:
    mysql开启skip-name-resolve 导致root@127.0.0.1(localhost)访问引发的ERROR 1045 (28000)错误解决方案
    php的类型运算符instanceof(用于确定一个 PHP 变量是否属于某一类 class 的实例)
    PHP通过__call实现简单的AOP(主事务后的其他操作)比如前置通知,后置通知
    页面返回刷新或H5监听(手机的)返回键
    微信公众号分享的引导页(附素材)
    mysql服务器无法连接10055错误解决示例
    Eclipse安装svn插件的几种方式
    mysql导入和导出数据
    eclipse的常用快捷键
    springmvc乱码配置
  • 原文地址:https://www.cnblogs.com/darlinFly/p/9337823.html
Copyright © 2011-2022 走看看