【連結串列問題】判斷無環單鏈表是否相交
阿新 • • 發佈:2018-12-30
目錄
題目
現在有兩個無環單鏈表,若兩個連結串列的長度分別為m和n,判斷這兩個連結串列是否相交。
給定兩個連結串列的頭結點headA和headB,請返回一個bool值,代表這兩個連結串列是否相交。保證兩個連結串列長度小於等於500。
思路
首先明確,兩個連結串列相交是指從某個節點開始,儲存的下一個節點的地址相同。相交的結點即為公共節點,這個節點之後的節點都是公共節點。
雜湊表判斷兩連結串列是否相交
時間複雜度為O(n + m),額外空間複雜度為O(N),N為大於len1的常數
先遍歷第一個連結串列,把第一個連結串列的節點放入雜湊表中,遍歷第二個節點,一旦發現有相同節點即說明兩個連結串列相交。時間複雜度為O(len1+len2)。雜湊表儲存的應該是節點的地址,關鍵字通過雜湊函式求得。
可用除k取餘法,如用陣列表示的雜湊表為ListNode * l[9] = {NULL};
那麼在設定hash函式時,取不大於9的質數作為被除數,如7.
int Hash(void* key){//key傳入的節點地址
int Ckey = (int)key;
return Ckey % 7;//除留取餘法
}
根據連結串列相交性質判斷
時間複雜度為O(n + m),額外空間複雜度為O(1),N為大於len1的常數
如果兩無環連結串列相交,相交節點之後的結點都是公共節點.因此一定是下面這種形式:
因此可按照以下步驟計算:
遍歷兩個連結串列,得到兩個連結串列長度len1和len2,假設len1>len2,將len1遍歷到(len1-len2)的位置,此後兩個連結串列長度相等,即可以逐步遍歷並進行對應的判斷。
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} };*/ class CheckIntersect { public: bool chkIntersect(ListNode* headA, ListNode* headB) { // write code here if(headA==NULL || headB == NULL) return false; else{ int size1 = 0;int size2 = 0; ListNode*temp = headA;//求第一個連結串列的長度 while(temp!=NULL){ size1++; temp = temp->next; } temp = headB;//求第二個連結串列的長度 while(temp!=NULL){ size2++; temp = temp->next; } ListNode* longer = NULL;ListNode*shorter = NULL; longer = size1>=size2?headA:headB; shorter = size1>=size2?headB:headA; int gap = size1>=size2?(size1-size2):(size2-size1); for(int i =0;i<gap;i++){//把兩個連結串列尾對齊,開頭長的部分砍掉 longer = longer->next; } while(longer!=NULL && shorter !=NULL){ if(longer == shorter ) return true; longer = longer->next; shorter = shorter->next; } return false; } } };
自己第一次做沒做對...在遍歷求兩個連結串列長度的時候,temp忘了指向自己的下一個節點,這樣導致無限迴圈。