题目
输入两个链表,找到它们的第一个公共节点。链表节点定义如下:
class ListNode{
public int n;
public ListNode next;
public ListNode(int n){
this.n = n;
next = null;
}
}
思路
思路一
暴力算法,对于第一个链表的每个节点,遍历第二个节点的所有节点,判断是否有相同的节点。时间复杂度为O(mn);
思路二
我们观察给的整个链表的结构,发现从第一个公共节点后面都是公共节点,所以可以从后往前遍历,找到最后一个公共节点就是正向的第一个公共节点。
可以用栈来辅助保存这个链表的节点,然后用后进先出的方法来判断。
时间复杂度为O(m+n),但是需要消耗m+n的栈空间。
思路三
可以发现一个最大的问题就是两个链表的长度不一样导致不能从前面开始一一比较,我们可以先得到两个链表的长度,然后把长点的链表先遍历到剩余长度与短链表的长度一致,这样就可从开始一一比较两个节点是否相同。
代码
public static ListNode findFirstCommonNode(ListNode head1,ListNode head2){
int listNodelLength = getListLength(head1);
int listNode2Length = getListLength(head2);
int lengthDif = listNodelLength - listNode2Length;
ListNode listLong = head1;
ListNode listShort = head2;
if(listNode2Length > listNodelLength){
listLong = head2;
listShort = head1;
lengthDif = listNode2Length - listNodelLength;
}
for(int i = 0;i < lengthDif;i++){
listLong = listLong.next;
}
while((listLong != null) && (listShort != null) && (listLong != listShort)){
listLong = listLong.next;
listShort = listShort.next;
}
return listLong;
}
public static int getListLength(ListNode l){
if(l == null)return 0;
int count = 1;
while(l != null){
l = l.next;
count++;
}
return count;
}
}
class ListNode{
public int n;
public ListNode next;
public ListNode(int n){
this.n = n;
next = null;
}
public static ListNode findFirstCommonNode(ListNode head1,ListNode head2){
int listNodelLength = getListLength(head1);
int listNode2Length = getListLength(head2);
int lengthDif = listNodelLength - listNode2Length;
ListNode listLong = head1;
ListNode listShort = head2;
if(listNode2Length > listNodelLength){
listLong = head2;
listShort = head1;
lengthDif = listNode2Length - listNodelLength;
}
for(int i = 0;i < lengthDif;i++){
listLong = listLong.next;
}
while((listLong != null) && (listShort != null) && (listLong != listShort)){
listLong = listLong.next;
listShort = listShort.next;
}
return listLong;
}
public static int getListLength(ListNode l){
if(l == null)return 0;
int count = 1;
while(l != null){
l = l.next;
count++;
}
return count;
}
}
class ListNode{
public int n;
public ListNode next;
public ListNode(int n){
this.n = n;
next = null;
}
}
总结
本题需要发现两个链表组合起来的规律。