36 两个链表的第一个结点

Posted shareidea94

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了36 两个链表的第一个结点相关的知识,希望对你有一定的参考价值。

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

这个题目有很多个思路,  假设链表一长度为m,链表二长度为n

思路一: 找出两个链表长度差,然后同时遍历

时间复杂度为O( maxm,n)

空间复杂度为O(1)

但是代码太多了,敲着真得很不爽

技术图片
 1 /*
 2 public class ListNode 
 3     int val;
 4     ListNode next = null;
 5 
 6     ListNode(int val) 
 7         this.val = val;
 8     
 9 */
10 public class Solution 
11     public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) 
12         //考虑特殊情况
13         if (pHead1 == null || pHead2 == null)
14             return null;
15         //定义新的两个指针
16         ListNode temp1 = pHead1;
17         ListNode temp2 = pHead2;
18         //比较两个链表长度,并决定新的指针的位置
19         int length1 = getLength(pHead1);
20         int length2 = getLength(pHead2);
21         if(length1 >= length2)//说明链表一长,所以链表一先走差值
22             int diff = length1 - length2;
23             while(diff != 0 )
24                 temp1 = temp1.next;
25                 diff--;
26             
27         else//说明链表二长,所以链表二先走差值
28             int diff= length2 - length1;
29             while(diff!=0)
30                 temp2 = temp2.next;
31                 diff--;
32             
33         
34         
35         //最终的结果遍历
36         while(temp1 != temp2)
37             temp1 = temp1.next;
38             temp2 = temp2.next;
39         
40         return temp1;
41     
42     //求链表长度的函数
43     public int getLength(ListNode head)
44         int length =0;
45         ListNode temp= head;
46         while(temp != null)
47             length++;
48             temp = temp.next;
49          
50         return length;
51     
52     
53 
View Code

 

思路二: 不同写getLength函数,间接找出链表长度差,然后同时遍历

 

 1 public class Solution 
 2     public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) 
 3         //考虑特殊情况
 4         if (pHead1 == null || pHead2 == null)
 5             return null;
 6         //将两个链表结点赋值给两个指针
 7         ListNode temp1 = pHead1;
 8         ListNode temp2 = pHead2;
 9         //长度相同有公共结点,第一次就遍历到;没有公共结点,走到尾部NULL相遇,返回NULL
10         //长度不同有公共结点,第一遍差值就出来了,第二遍一起到公共结点;没有公共,一起到结尾NULL。
11         //while(temp1.val != temp2.val ),这句话会报java.lang.NullPointerException的错误
12         while(temp1 != temp2)
13             temp1 = (temp1 == null ? pHead2 : temp1.next);
14             temp2 = (temp2 == null ? pHead1 : temp2.next);
15         
16         return temp2;
17     
18 

 

思路三:利用HahMap

时间复杂度: 创建第一个链表的HashMap的时间开销加上扫面第二个链表的时间开销 O(m)+O(n)

空间复杂度: O(m) 或者 O(n)

 1 import java.util.HashMap;
 2 public class Solution 
 3     public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) 
 4         //新建两个指针
 5         ListNode current1 = pHead1;
 6         ListNode current2 = pHead2;
 7         HashMap<ListNode, Integer> hashMap = new HashMap<ListNode, Integer>();
 8         //将第一个链表中的所有结点都放入HashMap中
 9         while (current1 != null) 
10             hashMap.put(current1, null);
11             current1 = current1.next;
12         
13         //若另外一个链表中有相容的结点,肯定会在HashMap中有,跳出while循环即可
14         while (current2 != null) 
15             if (hashMap.containsKey(current2))
16                 return current2;
17             current2 = current2.next;
18         
19         //此处返回的是两个链表没有公共结点的情况
20         return null;
21  
22     
23 
24  

 

 思路四:利用堆栈.总的来说就是,先各自压栈,然后弹栈找出相同的最后一个相同的节点,即第一个相同的节点

 1 import java.util.Stack;
 2 public class Solution 
 3     public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) 
 4     if (pHead1 == null || pHead2 == null) 
 5             return null;
 6         
 7         Stack<ListNode> stack1 = new Stack<>();
 8         Stack<ListNode> stack2 = new Stack<>();
 9  
10         while (pHead1 != null) 
11             stack1.push(pHead1);
12             pHead1 = pHead1.next;
13         
14  
15         while (pHead2 != null) 
16             stack2.push(pHead2);
17             pHead2 = pHead2.next;
18         
19  
20         ListNode commonListNode = null;
21  
22         while (!stack1.isEmpty() && !stack2.isEmpty() && stack1.peek() == stack2.peek() ) 
23             stack2.pop();
24             commonListNode = stack1.pop();
25         
26  
27         return commonListNode;
28     
29 

 

以上是关于36 两个链表的第一个结点的主要内容,如果未能解决你的问题,请参考以下文章

36剑指offer--两链表的第一个公共结点

剑指offer系列——36.两个链表的第一个公共结点

剑指offer 36.时间空间效率的平衡两个链表的第一个公共结点

36.两个链表的第一个公共节点。

剑指offer36 两个链表的第一个公共子节点

两个链表的第一个公共结点