6.劍指offer-輸出兩個鏈表的公共節點

1.題目描述

輸入兩個鏈表,找出它們的第一個公共結點。

鏈表結構如下:

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};

2.基本思路

設鏈表pHead1的長度爲m,pHead2的長度爲n.

方法1:

  • 先遍歷pHead1,將其中每一個節點都存儲起來在一個hash表中
  • 再從pHead2頭節點開始遍歷,邊遍歷邊查詢,第一次遇到的在hash表中存在的節點即爲兩個鏈表的公共節點的頭節點,輸出即可

方法1的時間複雜度爲O(m+n) ,空間複雜度爲O(m)

方法2:

  • 求出兩個鏈表的長度m和n
  • 根據鏈表的長度,用一先一後兩個指針在兩個鏈表上,開始遍歷。當兩個指針相等的時候,則此時指針指向的節點即爲:兩者的公共節點

方法2的時間複雜度爲O(m+n) ,但是空間複雜度爲O(1)

3.代碼如下

方法1:

    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(pHead1==NULL | pHead2==NULL){
            return NULL;
        }
        ListNode *p=pHead1;
        unordered_map<ListNode*,int> hash;  // 用set等其他容器當然也可以
        while(p!=NULL){
            hash[p]=0;
            p=p->next;
        }
        p=pHead2;
        while(p!=NULL && hash.find(p)==hash.end()){
            p=p->next;
        }
        return p;   
    }

方法2:

    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(pHead1==NULL || pHead2==NULL){
            return NULL;
        }
        int m,n;
        ListNode *p,*p1;
        p=pHead1;
        p1=pHead2;
        m=0;
        n=0;
        while(p!=NULL){
            ++m;
            p=p->next;
        }

        while(p1!=NULL){
            ++n;
            p1=p1->next;
        }
        if(n<=m){
            int i=0;
            p=pHead1;
            while(i < (m-n)){
                p=p->next;
                ++i;
            }
            p1=pHead2;
        }else{
            int i=0;
            p=pHead2;
            while(i<(n-m)){
                p=p->next;
                ++i;
            }
            p1=pHead1;
        }

        while(p!=p1){
            p1=p1->next;
            p=p->next;
        }
        return p;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章