1. 程式人生 > >【連結串列問題】判斷無環單鏈表是否相交

【連結串列問題】判斷無環單鏈表是否相交

目錄

 

題目

思路

雜湊表判斷兩連結串列是否相交

根據連結串列相交性質判斷


題目

現在有兩個無環單鏈表,若兩個連結串列的長度分別為m和n,判斷這兩個連結串列是否相交。

給定兩個連結串列的頭結點headAheadB,請返回一個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忘了指向自己的下一個節點,這樣導致無限迴圈。