两个链表的第一个公共结点
题目链接
- 首先我们想到的就是先让一个链表先遍历差值个单位节点,当两个链表长度相等时,同时遍历如果有相等节点就是有公共节点!
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode cur1 = pHead1;
ListNode cur2 = pHead2;
int size1 = 0;
int size2 = 0;
while(cur1!=null){
cur1 = cur1.next;
size1++;
}
while(cur2!=null){
cur2 = cur2.next;
size2++;
}
if(size1>size2){
int len = size1 - size2;
while(len-->0){
pHead1 = pHead1.next;
}
}else{
int len = size2 - size1;
while(len-->0){
pHead2 = pHead2.next;
}
}
while(pHead1!=null){
if(pHead1.val==pHead2.val){
return pHead1;
}
pHead1 = pHead1.next;
pHead2 = pHead2.next;
}
return null;
}
}
- 上面的方法就是借助了路程相等,相同速度如果有公共节点肯定会相遇,我们可以将两个链表加起来,就是一个链表遍历结束,就从另一个链表的开始遍历,另一链表也是如此,就保证了长度相等,就和上面方法类似了,看下面动图分析!
- 通过两个指针速度相同,走过的路程相同必会相遇!
- cur1 走完 L1,cur1指向 L2,cur2走完L2,指向L1!
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode cur1 = pHead1;
ListNode cur2 = pHead2;
while(cur1!=cur2){
cur1 = (cur1==null) ? pHead2 : cur1.next;
cur2 = (cur2 == null) ? pHead1 : cur2.next;
}
return cur1;
}
}
链表中环的入口结点
链表中环的入口结点
- 这里通过定义两个指针,
slow
走一步,fast
走2步,如果有环肯定会相遇! - 快慢指针,这里通过 时间相同,
fast
指针速度是slow
指针的2倍,那么路程也是2倍关系! - 通过位移关系找出了,入口和相遇点的关系,
L = C-x
开始节点到入口的距离等于相遇点到环的距离 - 那么我们先通过快慢指针找到相遇点,然后再走
L
单位就是入口节点位置!
public ListNode EntryNodeOfLoop(ListNode pHead) {
ListNode slow = pHead,fast = pHead;
while(fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast==slow){
slow = pHead;
while(fast!=slow){
slow = slow.next;
fast = fast.next;
}
return fast;
}
}
return null;
}
- 注意,这里的快慢指针,只能是一个走1步,一个走2步!其他关系可能无法保证相遇!