本题为剑指offer面试题37
牛客网测试地址:https://www.nowcoder.com/questionTerminal/6ab1d9a29e88450685099d45c9e31e46
[编程题]两个链表的第一个公共结点
- 热度指数:42895时间限制:1秒空间限制:32768K
- 算法知识视频讲解
输入两个链表,找出它们的第一个公共结点。
package go.jacob.day511;
import java.util.Stack;
/**
* @author Administrator
* 本题有两种思想
* 思想一:用堆栈:缺点是开辟了辅助空间n+m,时间复杂度是O(n+m)
* 思想二:先分别获得链表长度,获得两个链表的长度差a,则下次遍历的时候在较长链表上先走a步
*
* 基础:因为ListNode是单链表,所以第一个公共点以后的节点完全相同
*/
public class Demo2 {
/*
* 方法一:使用堆栈 缺点:开辟了n+m个辅助空间
*/
public ListNode FindFirstCommonNode_1(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null)
return null;
ListNode result = null;
ListNode tmp = null;
// 新建两个栈用来存储两个链表的所有节点。(链表尾在栈顶)
Stack<ListNode> stack1 = new Stack<ListNode>();
Stack<ListNode> stack2 = new Stack<ListNode>();
// 节点入栈
while (pHead1 != null) {
stack1.push(pHead1);
pHead1 = pHead1.next;
}
while (pHead2 != null) {
stack2.push(pHead2);
pHead2 = pHead2.next;
}
// 依次判断栈顶节点是否相同,第一个公共节点即为栈pop出的最后相同节点
while (!stack1.isEmpty() && !stack2.isEmpty()) {
tmp = stack1.pop();
if (tmp == stack2.pop())
result = tmp;
else
break;
}
return result;
}
/*
* 方法二:获取链表长度,再从相对位置开始遍历 比方法一好
*/
public ListNode FindFirstCommonNode_2(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null)
return null;
ListNode node1 = pHead1, node2 = pHead2;
int length1 = 0, length2 = 0;
// 遍历两个链表
while (node1 != null) {
length1 += 1;
node1 = node1.next;
}
while (node2 != null) {
length2 += 1;
node2 = node2.next;
}
//对较长链表的头结点进行处理,先走k步
if (length1 >= length2) {
int k = length1 - length2;
while (k != 0) {
pHead1 = pHead1.next;
k--;
}
} else {
int k = length2 - length1;
while (k != 0) {
pHead2 = pHead2.next;
k--;
}
}
//遍历第一个相同的节点就是第一个公共节点
while (pHead1 != pHead2) {
pHead1 = pHead1.next;
pHead2 = pHead2.next;
}
return pHead1;
}
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
}