問題描述:
乙個比較經典的問題,判斷兩個鍊錶是否相交,如果相交找出他們的交點。
思路:1、碰到這個問題,第一印象是採用hash來判斷,將兩個鍊錶的節點進行hash,然後判斷出節點,這種想法當然是可以的。
2、當然採用暴力的方法也是可以的,遍歷兩個鍊錶,在遍歷的過程中進行比較,看節點是否相同。
3、第三種思路是比較奇特的,在程式設計之美上看到的。先遍歷第乙個鍊錶到他的尾部,然後將尾部的next指標指向第二個鍊錶(尾部指標的next本來指向的是null)。這樣兩個鍊錶就合成了乙個鍊錶,判斷原來的兩個鍊錶是否相交也就轉變成了判斷新的鍊錶是否有環的問題了:即判斷單鏈表是否有環?
這樣進行轉換後就可以從鍊錶頭部進行判斷了,其實並不用。通過簡單的了解我們就很容易知道,如果新煉表是有環的,那麼原來第二個鍊錶的頭部一定在環上。因此我們就可以從第二個鍊錶的頭部進行遍歷的,從而減少了時間複雜度(減少的時間複雜度是第乙個鍊錶的長度)。
下圖是乙個簡單的演示:
這種方法可以判斷兩個鍊錶是否相交,但不太容易找出他們的交點。
4、仔細研究兩個鍊錶,如果他們相交的話,那麼他們最後的乙個節點一定是相同的,否則是不相交的。因此判斷兩個鍊錶是否相交就很簡單了,分別遍歷到兩個鍊錶的尾部,然後判斷他們是否相同,如果相同,則相交;否則不相交。示意圖如下:
判斷出兩個鍊錶相交後就是判斷他們的交點了。假設第乙個鍊錶長度為len1,第二個問len2,然後找出長度較長的,讓長度較長的鍊錶指標向後移動|len1 - len2| (len1-len2的絕對值),然後在開始遍歷兩個鍊錶,判斷節點是否相同即可。
下面給出乙個簡單的實現:
typedef struct node_t
int data;//data}node;struct node_t *next; //next
node* find_node(node *head1, node *head2)
if(null == head1 || null == head2)通過上面的操作就可以找到兩個鍊錶的交點了。return null;//如果有為空的鍊錶,肯定是不相交的
node *p1, *p2;
p1 = head1;
p2 = head2;
int len1 = 0;
int len2 =0;
int diff = 0;
while(null != p1->next)
p1 = p1->next;
len1++;
while(null != p2->next)
p2 = p2->next;
len2++;
if(p1 != p2) //如果最後乙個節點不相同,返回null
return null;
diff = abs(len1 - len2);
if(len1 > len2)
p1 = head1;
p2 = head2;
else
p1 = head2;
p2 = head1;
for(int i=0; ip1 = p1->next;
while(p1 != p2)
p1 = p1->next;
p2 = p2->next;
return p1;
5、總結
上面的幾種方法中最後一種是比較不錯的,當然hash也是可以的。
問題的延伸:
如果原來的兩個鍊錶中有環怎麼處理?
判斷兩個鍊錶是否相交並找出交點
問題描述 乙個比較經典的問題,判斷兩個鍊錶是否相交,如果相交找出他們的交點。思路 1 碰到這個問題,第一印象是採用hash來判斷,將兩個鍊錶的節點進行hash,然後判斷出節點,這種想法當然是可以的。2 當然採用暴力的方法也是可以的,遍歷兩個鍊錶,在遍歷的過程中進行比較,看節點是否相同。3 第三種思路...
判斷兩個鍊錶是否相交並找出交點 筆記
本文內容並非全部為原創,新增個人想法僅做筆記之用。判斷兩個鍊錶是否相交的方法 相交鍊錶的特徵 如果兩個鍊錶相交,那麼交點以後的節點都相同,否則不相交。這個地球人都懂得 兩個鍊錶的節點進行hash,然後判斷節點hash值和節點的值是否相等來判斷。乙個鍊錶的尾部連線下乙個鍊錶的頭部,通過判斷新鍊錶是否有...
如何判斷兩個鍊錶是否相交並找出交點
情況1 兩個鍊錶均不含有環 1 直接法 採用暴力的方法,遍歷兩個鍊錶,判斷第乙個鍊錶的每個結點是否在第二個鍊錶中,時間複雜度為o len1 len2 耗時很大。2 hash計數法 如 果 兩個鍊錶相交,則兩個鍊錶就會有共同的結點 而結點位址又是結點唯一標識。因而判斷兩個鍊錶中是否存在位址一致的節點,...