题目:
编写一个程序,找到两个单链表相交的起始节点。
例如,下面的两个链表:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
在节点 c1 开始相交。
注意:
- 如果两个链表没有交点,返回
null
. - 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
思路:看到这个题并没有什么思路。。。。。。链表的题总是不会。。。。。。。然后就网上找了大神的代码,还有leetcode上提交最快的代码。下面就先看懂这两个代码吧。。。
思路1 :最快的代码
这个代码首先用来两个while循环到达链表末尾并得到链表中的节点数。如果链表相交最后一个节点一定是相等的,先判断最后一个节点。之后就类似将两个链表以链表结尾对齐,依次判断节点是否相等。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null) return null;
ListNode p = headA;
ListNode q = headB;
int pn = 1;
int qn = 1;
while(p.next != null){
pn++;
p = p.next;
}
while(q.next != null){
qn++;
q = q.next;
}
if(p != q) return null;
//reset p,q
p = headA;
q = headB;
if(pn > qn){
int d = pn - qn;
while(d > 0 && p != null){
p = p.next;
d--;
}
}else if(pn < qn){
int d = qn - pn;
while (d >0 && q != null){
q = q.next;
d--;
}
}
while(p != null && q != null){
if(p == q) return q;
p = p.next;
q = q.next;
}
return null;
}
}
思路2:大神们的代码
两个链表的长度如果相等直接比较找相等;如果长度不同,将短链表补在长链表后面,短链表补在长链表后面。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode listA = headA, listB = headB;
while (listA != null && listB != null) {
if (listA == listB) return listA;
listA = listA.next;
listB = listB.next;
if (listA == listB) return listA;
if (listA == null) listA = headB;
if (listB == null) listB = headA;
}
return listA;
}
}
注意:
(1)return可以用来退出整个函数,当然也可以退出整个循环
(2)listA == listB链表中这两个节点相等应该指的是指向的是同一个内存区域.==比较的是两个对象的内存地址是否相等。