Hiii ......
如果我们给出了两个链表(可能长度不同),那么从末端开始的几个节点是常见的...我们如何在最短的时间内找到第一个公共节点......?
这些名单是单独链接的。一些节点从最后是常见的,我们需要从它们中找到第一个共同的节点。
答案 0 :(得分:5)
总复杂性: O(n)
例如:
1→2→3→4-&将7-> 8
--------- 5→6-&将7-> 8
我们希望得到 7 ,因为它是第一个公共节点。
答案 1 :(得分:1)
假设每个链表都有一个完全唯一的集合,我看到的唯一方法是使用嵌套的for循环,效率非常低。如果数据集不是唯一的,您可以使用第三个(链接的)列表作为唯一节点的缓存,但仍然在查看最坏情况下的O(n²)
答案 2 :(得分:1)
O(n)解决方案,用于查找其中一个列表中具有相同值的第一个节点。然后,您可以从该节点中提取值。
除非另有说明,否则所有代码部分(注释)都是O(1)
,并且没有嵌套的O(n)
操作。因此整个解决方案是O(n)。
它的工作原理是计算每个列表中的元素,然后推进最长列表的指针,以便结束对齐。
然后以同步方式逐步浏览两个列表。如果节点匹配且先前未匹配,则会保存该节点(不,只要它们匹配,因为您希望序列中的最早匹配)。
如果它们不匹配,则保存该事实,以便后续匹配将被视为序列中最早的匹配。
当你到达两个列表的末尾时,你要么指出没有匹配(如果两个列表的最后一个节点不同),要么是序列中最早的匹配。
当然只有伪代码,因为它是作业:
def findCommonNode (head1, head2):
# Work out sizes O(n)
set count1 and count2 to 0
set ptr1 to head1
while ptr1 is not equal to NULL:
increment count1
set ptr1 to ptr1->next
set ptr2 to head2
while ptr2 is not equal to NULL:
increment count2
set ptr2 to ptr2->next
# If either size is 0, no match possible.
if count1 == 0 or count2 = 0:
return NULL
# Make the first list longer (or same size).
if count1 < count2:
swap count1 and count2
swap head1 and head2 (local copies only)
# Move through longest list until they're aligned O(n).
set ptr1 to head1
set ptr2 to head2
while count1 is greater than count2:
decrement count1
set ptr1 to ptr1->next
# Initially mark as non-match.
set retptr to NULL
# Process both (aligned) lists O(n).
while ptr1 is not equal to NULL:
# If equal and if first match after non-match, save position.
if ptr1->data is equal to ptr2.data:
if retptr is equal to NULL:
set retptr to ptr1
else:
# If not equal, mark as non-match.
set retptr to NULL
# Advance to next element in both lists.
set ptr1 to ptr1->next
set ptr2 to ptr2->next
# Return the earliest match.
return retptr
假设您有两个列表1,2,3,4,5,5,6,7,8,9
和0,6,9,8,9
。根据大小差异对齐这些并推进列表1指针,您将得到:
v
1 2 3 4 5 5 6 7 8 9
0 6 9 8 9
^
然后将match设置为NULL并开始处理。它们不匹配(5/0
),因此您将第一个匹配节点设置为NULL(即使它已经为NULL)并前进到6/6
。
这些(6/6
)匹配(并且当前匹配为NULL),因此您将其中一个的地址保存为匹配,然后前进。
7/9
不匹配,因此您再次将匹配设置为NULL,然后前进。
8/8
匹配且匹配为NULL,因此您再次将匹配设置为其中一个,然后前进。
9/9
也匹配,但匹配已设置,因此您不会更改它。然后推进两个列表中的元素。
然后返回匹配为8
个节点之一。这是你最常见的尾随部分。