《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及这里:https://github.com/alexhagiopol/cracking-the-coding-interview。源码中节点以及功能函数定义参见这里:2.1 移除重复节点
template <typename T>
SinglyLinkedNode<T>* intersection(SinglyLinkedNode<T>* head1, SinglyLinkedNode<T>* head2)
{
if(head1=nullptr || head2=nullptr)
{
return nullptr;
}
SinglyLinkedNode<T>* runner1 = head1;
SinglyLinkedNode<T>* runner2 = head2;
int length1 = 1;
int length2 = 1;
// Advance List 1 to get the last node pointer and its size.
while (runner1->getNext() != nullptr)
{
runner1 = runner1->getNext();
length1++;
}
// Advance List 2 to get the last node pointer and its size.
while (runner2->getNext() != nullptr)
{
runner2 = runner2->getNext();
length2++;
}
// if the last node reference(not node's value) of two lists are different,return flase;
if (runner1 != runner2)
{
return nullptr;
}
//Compute the difference of two lists
int sizeDiff = abs(length1 - length2);
// determine which lists is longer
SinglyLinkedNode<T>* larger =length1 < length2 ? head2 : head1;
SinglyLinkedNode<T>* smaller = length1 < length2 ? head1 : head2;
/* Advance longer length list to the pointer that has same number
of nodes with the shorter list from this node of the pointer points
to the last node of longer length list.*/
while (sizeDiff > 0)
{
larger = larger->getNext();
sizeDiff--;
}
/* Advance pointers simultaneously until they are equal.The node that this pointer refernced
is the intersection node of the two lists.*/
while (larger != smaller)
{
larger = larger->getNext();
smaller = smaller->getNext();
}
return smaller;
}
算法首先计算两个链表的长度,并将指针都定位到两个链表的最后一个节点。如果两个链表的最后一个节点不是同一个节点的引用则这两个链表肯定不相交。接着计算两个链表长度的差值,从长度较长的那个链表的头节点开始后移长度差值个数个节点,并将指针定位在这里,长度较短的那个链表的指针定位到头节点。然后比较定位点的指针如果相同则返回该指针,否则继续比较下一个指针直到到达链表的尾部空节点。
该算法的空间复杂度为O(1)。该算法的时间复杂度为O(M+N)。M、N分别为两个链表的长度。