劍指offer 划水鏈表2

(1)兩個鏈表的第一個公共結點

字節跳動的HR人真的很好  和藹可親  就像傅姓洲洲學長一樣  人超好  給我出的題很簡單,,可惜我  面字節一點沒準備  怕是一年多沒寫代碼  我連這個都沒寫出來  我人傻了  我是飛舞

首先是比較常規的寫法.我們維護一個map,然後遍歷一下這倆鏈表 ,找見相同的就返回好咯.

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        map<ListNode*,int>m;
        while(pHead1||pHead2)
        {
            if(pHead1){
                if(m.find(pHead1)!=m.end()){return pHead1;}
                else{
                    m.insert(make_pair(pHead1,1));
                }
                pHead1=pHead1->next;
            }
            if(pHead2){
                if(m.find(pHead2)!=m.end()){return pHead2;}
                else{
                    m.insert(make_pair(pHead2,1));
                }
                pHead2=pHead2->next;
            }
        }
        return NULL;
    }
};

然後hr小哥又問   你能不能別靠map   ,我說  我行!當我不行的時候我就站到行人道上   這樣我就變成了行人

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(pHead1==NULL||pHead2==NULL)return NULL;
        ListNode * p1,*p2;
        p1=pHead1;p2=pHead2;
        while(p1&&p2&&p1!=p2)
        {
            p1=p1->next;
            p2=p2->next;
            if(p1==p2)return p1;
            if(p1==NULL)p1=pHead2;
            if(p2==NULL)p2=pHead1;
        }
        return p1;
    }
};

(2)鏈表中環的入口節點....捂臉.我第一次面試的時候,劍指刷的只剩了這個題,然後他就考了......有時候就是這麼點背.......但是主要還是怪自己菜   真的飛舞

首先是比較好想的辦法.寫一個map,然後往裏存節點.掃一遍就能找到如果有環.環的開始節點.

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead==NULL)return NULL;
        ListNode * p1=pHead;
        map<ListNode* ,int>m;
        while(p1)
        {
            if(m.find(p1)!=m.end())return p1;
            m.insert(make_pair(p1,1));
            p1=p1->next;
        }
        return NULL;
    }
};

這時候...我不等你說了  不用map是吧?

那可以循環.找有沒有環,找環的長度,然後快慢指針直接求環的開始節點.

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead==NULL||pHead->next==NULL)return NULL;
        ListNode * p1,*p2;
        p1=p2=pHead;
        while(p1&&p2&&p2->next)
        {
            p1=p1->next;
            p2=p2->next->next;
            if(p1==p2)break;
        }
        if(p1==NULL||p2==NULL)return NULL;
        int len=1;
        p1=p1->next;
        while(p1!=p2)
        {
            p1=p1->next;len++;
        }
        p1=p2=pHead;
        while(len--)
        {
            p2=p2->next;
        }
        while(p1&&p2&&p1!=p2)
        {
            p1=p1->next;p2=p2->next;
        }
        return p1;
    }
};

(3)刪除列表中重複的節點

注意審題,,不是保留一個 ,,是重複的都刪掉.

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if(!pHead||!pHead->next)return pHead;
        ListNode * p=pHead;
        ListNode * ans=new ListNode(0);
        ans->next=pHead;
        ListNode * last=ans;
        while(p&&p->next)
        {
            if(p->val==p->next->val)
            {
                while(p&&p->next&&p->val==p->next->val)
                {
                    p=p->next;
                }
                p=p->next;
                last->next=p;
            }
            else
            {
                last=p;
                p=p->next;
            }
        }
        return ans->next;
    }
};

這裏寫來寫去到處越界,索性不要考慮哪裏需不需要寫判空的條件,直接都寫上就老了.因爲有可能這個鏈表就是一個222這種 所以先整一個新的頭結點指向鏈表頭,再做刪重的操作.

看見題解裏有遞歸寫法...我總感覺這題寫遞歸更難想........咱也貼一個遞歸的寫法好了.

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if(!pHead||!pHead->next)return pHead;
        ListNode * p=pHead;
        if(p&&p->next&&p->val==p->next->val)
        {
            while((p&&p->next&&p->val==p->next->val))
            p=p->next;
            return deleteDuplication(p->next);
        }
        else
        {
            p->next=deleteDuplication(p->next);
            return p;
        }
        return pHead;
    }
};

鏈表就到這裏,下一篇寫二叉樹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章