输入两个链表,找出它们的第一个公共结点。
代码
解法一
利用栈的后入先出特性,来从尾部找第一个公共节点
static class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
/**
* 两个链表的第一个公共结点
* 1 -> 2 -> 3 -> 4
* +
* 11 -> 18 -> 19 -> 3 -> 4
* 这种链表可以认为是Y型链表,从前往后找比较困难,但是链表只保存next节点,也不好从后往前找
* 所以借助栈结构,遍历链表,依次入栈,结合栈的后进先出特性,来从后往前比较两个链表,直至找到第一个公共节点
* @param root1
* @param root2
* @return
*/
public static int findShareNode(ListNode root1, ListNode root2) {
if (root1 == null || root2 == null) {
throw new IllegalArgumentException("root1 or root 2 is null");
}
Stack<ListNode> stack1 = new Stack<>();
Stack<ListNode> stack2 = new Stack<>();
while (root1 != null) {
stack1.push(root1);
root1 = root1.next;
}
int result = -1;
while (root2 != null) {
stack2.push(root2);
root2 = root2.next;
}
while (!stack1.isEmpty() && !stack2.isEmpty()) {
root1 = stack1.pop();
root2 = stack2.pop();
if (root1.val == root2.val) {
result = root1.val;
} else {
break;
}
}
return result;
}
解法二
计算两个链表的长度,使较长的链表先移动链表长度差的步长,然后再依次比较两个链表相同位置上的节点。
/**
* 两个链表的第一个公共结点
* 1 -> 2 -> 3 -> 4
* +
* 11 -> 18 -> 19 -> 3 -> 4
* 这种链表可以认为是Y型链表,从上面可以看出,11这个节点没有可比性,因为两个链表不等长,多出的部分不需要进行比较
* 所以先将较长的链表走一定的步数,当其剩余的长度和另一个链表长度相等时,同时遍历,进行比较,找出第一个公共节点
* @param root1
* @param root2
* @return
*/
public static int findShareNode2(ListNode root1, ListNode root2) {
if (root1 == null || root2 == null) {
throw new IllegalArgumentException("root1 or root 2 is null");
}
int root1Length = 0;
int root2Length = 0;
ListNode tempRoot1 = root1;
ListNode tempRoot2 = root2;
// 计算root1的长度
while (tempRoot1 != null) {
tempRoot1 = tempRoot1.next;
root1Length++;
}
// 计算root2的长度
while (tempRoot2 != null) {
tempRoot2 = tempRoot2.next;
root2Length++;
}
// 计算两个链表的长度差
int i = Math.abs(root1Length - root2Length);
// 判断先让哪个链表走k步,k=length1-length2
// 从而使得两个链表以相同的长度来进行查找第一个公共节点
if (root1Length > root2Length) {
while (i > 0 && root1 != null) {
root1 = root1.next;
i--;
}
} else {
while (i > 0 && root2 != null) {
root2 = root2.next;
i--;
}
}
// 此时两个链表长度一致,依次对比相同位置上的节点
// 如果一致,说明是第一个公共节点
while (root1 != null && root2 != null) {
if (root1.val == root2.val) {
return root1.val;
}
root1 = root1.next;
root2 = root2.next;
}
return -1;
}