简单算法 两个链表的第一个公共结点(java)
描述
输入两个无环的单链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
示例1
输入:
{1,2,3},{4,5},{6,7}
返回值:
{6,7}
说明:
第一个参数{1,2,3}代表是第一个链表非公共部分,第二个参数{4,5}代表是第二个链表非公共部分,最后的{6,7}表示的是2个链表的公共部分
这3个参数最后在后台会组装成为2个两个无环的单链表,且是有公共节点的
想法:
因为要寻找公共节点,我的想法是利用一个中间节点通过比较来获取公共节点
其余两个方法我是从题解区看到觉得简洁明了
方法1:
代码:
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1 == null || pHead2 == null) return null;
ListNode nex = null;
while(pHead1 != null){
nex = pHead2;
while(nex !=null){
if(nex == pHead1) return nex;
nex = nex.next;
}
pHead1 = pHead1.next;
}
return null;
}
方法二:
双指针:因为要寻找公共节点,我们不难发现两个结点如果遍历所有路径,最后的路径长度是一样的所以我们可以利用这点,使用该方法,让两个结点都遍历完所有路径,若有结点相交。判断停止即可,如无节点,两个结点遍历完全指向空结点
代码:
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode a = pHead1;
ListNode b = pHead2;
while(a != b){ // 判断 a,b在第二次遍历对方链表时是否相遇
a = a == null ? pHead2 : a.next;
b = b == null ? pHead1 : b.next;
}
return a; // 最终返回a, b都行,最终a,b是相同结点,或者都为空
}
方法3:
stack解法:
两个链表先分别进栈
再依次出栈,从后向前遍历遇到第一个不相等的节点
返回上一个相同节点即可
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode a = null;
Stack<ListNode> s1 = new Stack<>();
Stack<ListNode> s2 = new Stack<>();
ListNode l1 = pHead1;
ListNode l2 = pHead2;
while( l1 != null){
s1.push(l1);
l1 = l1.next;
}
while( l2 != null){
s2.push(l2);
l2 = l2.next;
}
while(!s1.isEmpty() && !s2.isEmpty()){
if(s1.peek() != s2.peek())
return a;
else {
a = s1.peek();
s1.pop();
s2.pop();
}
}
return a;
}