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
思路二: 不同写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 两个链表的第一个结点的主要内容,如果未能解决你的问题,请参考以下文章