【在线编程】两个链表的第一个公共结点
【问题描述】
输入两个链表,找出它们的第一个公共结点。
【解题思路 & Java实现】
方法一:如果两个链表存在公共结点,那么这两个链表一定呈 Y 形,公共结点后面的所有结点都是相同的。我们让长链表先走,知道走到与短链表的头部位置,然后两者并驾齐驱,直到遇到第一个公共结点。这个方法需要分别遍历两次链表。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
int len1 = 0;
int len2 = 0;
int count;
//计算 pHead1 的长度
ListNode p = pHead1;
while (p != null) {
len1++;
p = p.next;
}
//计算 pHead2 的长度
p = pHead2;
while (p != null) {
len2++;
p = p.next;
}
//长的先走 count 步,与短的达到同一起点
if (len1 >= len2) {
count = len1 - len2;
while (count-- > 0) {
pHead1 = pHead1.next;
}
} else {
count = len2 - len1;
while (count-- > 0) {
pHead2 = pHead2.next;
}
}
//两者在同一起点同时走,知道遇到公共结点
while (pHead1 != null && pHead2 != null) {
if (pHead1 == pHead2) {
return pHead1;
}
pHead1 = pHead1.next;
pHead2 = pHead2.next;
}
return null;
}
}
方法二:借助两个栈,同时从后往前遍历两个链表,找到最后一个公共结点即可。只需遍历一遍列表。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.Stack;
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
Stack<ListNode> stack1 = new Stack<>();
Stack<ListNode> stack2 = new Stack<>();
//将 pHead1 链表压住栈 stack1
while (pHead1 != null) {
stack1.push(pHead1);
pHead1 = pHead1.next;
}
//将 pHeaf2 链表压入栈 stack2
while (pHead2 != null) {
stack2.push(pHead2);
pHead2 = pHead2.next;
}
//比较两个栈的栈顶,即从后往前比较连个链表,最后一个公共结点即为第一个公共结点
ListNode result = null;
while (!stack1.isEmpty() && !stack2.isEmpty() && stack1.peek() == stack2.peek()) {
stack1.pop();
result = stack2.pop();
}
return result;
}
}
方法三:借用 HashSet,只遍历一边列表。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.HashSet;
public class Solution {
public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
HashSet<ListNode> set1 = new HashSet<>();
while (pHead1 != null) {
set1.add(pHead1);
pHead1 = pHead1.next;
}
while (pHead2 != null) {
if (set1.contains(pHead2)) {
return pHead2;
}
pHead2 = pHead2.next;
}
return null;
}
}