嗨......鏈接列表問題
如果我們給出兩個鏈表(可能長度不同),使得從最後幾個節點是常見的...我們如何找到第一個公共節點儘可能少的時間......?
該列表單獨鏈接。有些節點從最後是很常見的,我們需要找到它們之間第一個共同的節點。
嗨......鏈接列表問題
如果我們給出兩個鏈表(可能長度不同),使得從最後幾個節點是常見的...我們如何找到第一個公共節點儘可能少的時間......?
該列表單獨鏈接。有些節點從最後是很常見的,我們需要找到它們之間第一個共同的節點。
假設每個鏈表都有一個完全唯一的集合,我所看到的唯一方法是使用嵌套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