1、直接用set集合,时间复杂度O(n),空间复杂度O(n)
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
Set<ListNode> set = new HashSet<>();
while (pHead1 != null) {
set.add(pHead1);
pHead1 = pHead1.next;
}
while (pHead2 != null) {
if (set.contains(pHead2)) {
return pHead2;
}
pHead2 = pHead2.next;
}
return null;
}
}
2、直接stack,时间复杂度O(n),空间复杂度O(n)
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(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;
}
ListNode result = null;
while (!stack1.isEmpty() && !stack2.isEmpty()) {
if (stack1.peek() == stack2.peek()) {
result = stack1.pop();
stack2.pop();
} else {
return result;
}
}
return result;
}
}
3、先求出两个链表之间的差值,然长的先走差值步数,然后同时走,遇到相同的节点就返回即可,时间复杂度O(n),空间复杂度O(1)
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
ListNode node1 = pHead1;
ListNode node2 = pHead2;
int length1 = 0;
int length2 = 0;
while (pHead1 != null) {
length1++;
pHead1 = pHead1.next;
}
while (pHead2 != null) {
length2++;
pHead2 = pHead2.next;
}
//length1长,length1先走length1-length2步
int length = 0;
if (length1 > length2) {
length = length1 - length2;
while (length > 0) {
node1 = node1.next;
length--;
}
} else {
length = length2 - length1;
while (length > 0) {
node2 = node2.next;
length--;
}
}
while (node1 != null) {
if (node1 != node2) {
node1 = node1.next;
node2 = node2.next;
} else {
return node1;
}
}
return null;
}
}
4、首尾交叉相接法
我们准备两个指针分别从两个链表头同时出发,每次都往后一步,遇到末尾就连到另一个链表的头部,这样相当于每个指针都遍历了这个交叉链表的所有结点,那么它们相遇的地方一定是交叉的地方,即第一个公共结点。时间复杂度O(n),空间复杂度O(1)
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
ListNode node1 = pHead1;
ListNode node2 = pHead2;
//若是node1和node2没有交集,那么node1和node2各走一遍(pHead1.length+pHead2.length)
//最终两者都为null退出循环
//若是有交集,两者一定会在交集出相遇
while (node1 != node2) {
node1 = node1 == null ? pHead2 : node1.next;
node2 = node2 == null ? pHead1 : node2.next;
}
return node1;
}
}