两个链表的第一个公共结点
题目链接
首先我们想到的就是先让一个链表先遍历差值个单位节点,当两个链表长度相等时,同时遍历如果有相等节点就是有公共节点!
//先计算长度差,然后让一个指针先走差值单位! 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) { //定义2个指针! // cur1 走完 L1,又从 L2开始! // cur2 走完 L2,又从 L1开始! // 这里两个指针速度相同,走过的长度相等,如果有相同节点肯定相遇! ListNode cur1 = pHead1; ListNode cur2 = pHead2; while(cur1!=cur2){//不存在公共节点,两个指针会来到null相等退出循环! 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) { //快慢指针,利用链表头到入口距离 = 相遇点到入口距离! //所以当两个节点相遇后再走L距离就是入口位置! //相遇后让其中一个指针从链头开始走L,一个从相遇点开始! ListNode slow = pHead,fast = pHead; while(fast!=null&&fast.next!=null){//注意判断条件!!!! fast = fast.next.next; slow = slow.next; if(fast==slow){ //相遇! //让slow从头结点开始! slow = pHead; while(fast!=slow){ slow = slow.next; fast = fast.next; } return fast; } } return null; }