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
  • 相关阅读:
    20080619 SQL SERVER 输入 NULL 的快捷键
    20090406 Adobe的“此产品的许可已停止工作”错误的解决办法
    20080908 Office Powerpoint 2007 不能输入中文的解决办法
    20080831 ClearGertrude Blog Skin 's cnblogs_code class
    20080603 Facebook 平台正式开放
    20080519 安装 Microsoft SQL Server 2000 时提示 创建挂起的文件操作
    test
    Linux—fork函数学习笔记
    SOA的设计理念
    Why BCP connects to SQL Server instance which start with account of Network Service fail?
  • 原文地址:https://www.cnblogs.com/darlinFly/p/9337823.html
Copyright © 2011-2022 走看看