两个链表的第一个公共结点
题目描述:输入两个链表,找出它们的第一个公共结点。
思路:如果两个链表有公共结点,则第一个公共结点以及之后的所有结点都是重合的,即至少它们的尾结点是重合的。因为两个链表长度不一定相等,所以同步遍历时不能保证两个链表同时到达尾结点。假设一个链表比另一个多k个结点,先在长的链表上遍历k个结点即尾部对齐,再同步遍历,保证同时到达尾结点,即同时到达第一个公共结点。也就是说,同步遍历时第一个相同结点就是第一个公共结点。
步骤:
1 如果两个链表至少有一个是空,则返回null。
2 分别获取两个链表的长度len1和len2。
3 通过比较两个链表的长度来获取长度差k,并使长链表遍历k个结点。
4 通过同步遍历来查找第一个公共结点,如果查找到公共结点,则返回该结点。
5 返回null。
时间复杂度:O(len1+len2)。
Java代码:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode list1, ListNode list2) {
// 如果两个链表至少有一个是空,则返回null
if (list1 == null || list2 == null) {
return null;
}
// 分别获取两个链表的长度len1和len2
int len1 = getListLength(list1);
int len2 = getListLength(list2);
// 通过比较两个链表的长度来获取长度差k,并使长链表遍历k个结点
if (len1 > len2) {
list1 = walkSteps(list1, len1 - len2);
} else {
list2 = walkSteps(list2, len2 - len1);
}
// 通过同步遍历来查找第一个公共结点,如果查找到公共结点,则返回该结点
while (list1 != null) {
if (list1 == list2) {
return list1;
}
list1 = list1.next;
list2 = list2.next;
}
// 返回null
return null;
}
// 获取链表长度
private int getListLength(ListNode list) {
int len = 1;
while (list.next != null) {
list = list.next;
len++;
}
return len;
}
// 获取当前结点走了k步之后的结点
private ListNode walkSteps(ListNode list, int k) {
while (k-- > 0) {
list = list.next;
}
return list;
}
}
浙公网安备 33010602011771号