剑指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;
    }
};

链表就到这里,下一篇写二叉树

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