编写一个程序,找到两个单链表相交的起始节点。
例如,下面的两个链表:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
在节点 c1 开始相交。
注意:
- 如果两个链表没有交点,返回
null
. - 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
解法一:如果两个链长度相同的话,那么对应的一个个比下去就能找到,所以只需要把长链表变短即可。具体算法为:分别遍历两个链表,得到分别对应的长度。然后求长度的差值,把较长的那个链表向后移动这个差值的个数,然后一一比较即可。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null|| headB==null) return null;
ListNode dummy1=new ListNode(0);
ListNode dummy2=new ListNode(0);
dummy1.next=headA;
dummy2.next=headB;
ListNode curA=dummy1;
ListNode curB=dummy2;
int length1=getLength(curA);
int length2=getLength(curB);
if(length1>length2)
{
for(int i=0;i<length1-length2;i++)
{
curA=curA.next;
}
}else{
for(int i=0;i<length2-length1;i++)
{
curB=curB.next;
}
}
while (curA != null && curB != null && curA != curB) {
curA = curA.next;
curB = curB.next;
}
return (curA != null && curB != null) ?curA : null;
}
private int getLength(ListNode cur)
{
int k=0;
while(cur.next!=null)
{
k++;
cur=cur.next;
}
return k;
}
}
解法二:
我们可以用环的思想来做,我们让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况,一种情况是在交点处相遇,另一种情况是在各自的末尾的空节点处相等。为什么一定会相等呢,因为两个指针走过的路程相同,是两个链表的长度之和,所以一定会相等。这个思路真的很巧妙,而且更重要的是代码写起来特别的简洁
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null|| headB==null) return null;
ListNode a = headA, b = headB;
// while(a != b)
// {
// if(a==null) a=headB;
// else
// a=a.next;
// if(b==null) b=headA;
// else
// b=b.next;
// }
while (a != b) {
a = (a != null) ? a.next : headB;
b = (b != null) ? b.next : headA;
}
return a;
}
}
或者
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null|| headB==null) return null;
ListNode a = headA, b = headB;
while(a != b)
{
if(a==null) a=headB;
else
a=a.next;
if(b==null) b=headA;
else
b=b.next;
}
// while (a != b) {
// a = (a != null) ? a.next : headB;
// b = (b != null) ? b.next : headA;
// }
return a;
}
}