嗨......链接列表问题
如果我们给出两个链表(可能长度不同),使得从最后几个节点是常见的...我们如何找到第一个公共节点尽可能少的时间......?
该列表单独链接。有些节点从最后是很常见的,我们需要找到它们之间第一个共同的节点。
嗨......链接列表问题
如果我们给出两个链表(可能长度不同),使得从最后几个节点是常见的...我们如何找到第一个公共节点尽可能少的时间......?
该列表单独链接。有些节点从最后是很常见的,我们需要找到它们之间第一个共同的节点。
假设每个链表都有一个完全唯一的集合,我所看到的唯一方法是使用嵌套for循环,这将非常低效。如果数据集是不是唯一的,你可以使用第三方(链接)列表,只有独特的节点的缓存,但你仍然在寻找在澳的最坏情况(N²)
+1 ....我们应该为理论提供帮助,而不是为每个理论编码。他可能永远不会试图了解他是否为他的作业问题获取了熟悉的代码。 – loxxy 2010-09-18 05:29:16
我想我允许未排序的列表和不在相同的“索引”的匹配。这需要O(n²) – Puddingfox 2010-09-18 14:55:33
总复杂性:O(n)的
例如:
1-> 2-> 3-> 4-> 7-> 8
--------- 5-> 6-> 7-> 8
我们期望得到,因为它是第一个通用节点。
如果两个列表都有相同的no元素 – TalentTuner 2010-09-18 04:58:39
@saurabh,那么你的意思是他们根本没有共同的元素?或者他们有共同的元素,其次是非共同的元素? – Elisha 2010-09-18 05:11:20
@saurabh:然后在搜索第一个公共元素之前跳过零元素(记住检查下列元素是否匹配)。 – 2010-09-18 05:39:19
O(n)解决方案找到具有相同值的列表中的第一个节点。然后您可以从该节点提取值。
除非另有说明,并且没有嵌套的O(n)
操作,否则所有代码段(注释)均为O(1)
。因此整个解决方案是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
^
然后将匹配设置为NULL并开始处理。它们不匹配(5/0
),因此您将第一个匹配节点设置为NULL(即使它已经为NULL)并且前进到6/6
。
这些(6/6
)匹配(并且当前匹配为NULL),因此您将其中一个地址保存为匹配,然后前进。
7/9
不匹配,所以您再次将匹配设置为NULL,然后前进。
8/8
匹配和匹配是NULL,所以你再次将匹配设置为其中之一,然后前进。
9/9
也匹配但匹配已经设置,所以你不会改变它。提前,然后退出这两个列表中的元素。
然后您返回与8
节点之一匹配。这是您最常见的尾部部分。
这是作业 - 它听起来像它。请标记为这样。 – 2010-09-18 04:32:00
没有足够的信息。列表是单独还是双重链接?你有尾巴指针吗? “从最后几个节点常见”是什么意思? “第一常见”是指最接近头部还是最接近尾部? – 2010-09-18 04:32:24
至少在你发布之前先试着回答你的作业。 – 2010-09-18 05:24:14