• 算法复习:链表


    链表必须清楚掌握

    链表定义

    struct ListNode 
    {
        int val;
        ListNode *next;
    };

    创建链表头

    ListNode* creat()//创建头
    {
        struct ListNode *node=(struct ListNode *)malloc(sizeof(struct ListNode));
        node->next=NULL;
        return node;
    }

    创建一个新节点(插入时调用)

    ListNode* make_node(int num)//建新节点
    {
        struct ListNode *node=(struct ListNode *)malloc(sizeof(struct ListNode));
        node->val=num;
        node->next=NULL;
        return node;
    }

    插入新节点(尾插法)

    ListNode* insert(ListNode* head,int num)//尾插法
    {
        struct ListNode *str=(struct ListNode *)malloc(sizeof(struct ListNode));
        str=head;
        while(str->next)
        {
            str=str->next;
        }
        str->next=make_node(num);
        return head;
    }

    插入新节点(头插法)

    ListNode* insert(ListNode* head,int num)//头插法
    {
        struct ListNode *str=make_node(num);
        str->next=head->next;
        head->next=str;
        return head;
    }

    主函数举例(遍历输出,头节点不存数据)

    int main()
    {
        struct ListNode *head=creat();
        insert(head,1);
        insert(head,1);
        insert(head,2);
        insert(head,3);
        insert(head,4);
        insert(head,4);
        insert(head,5);
        struct ListNode *str=head->next;
        while(str)
        {
            cout<<str->val<<" ";
            str=str->next;
        }
        cout<<endl;
        return 0;
    }

    使用举例

    leetcode 206. 反转链表

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseList(ListNode* head) 
        {
            ListNode* last=NULL;
            ListNode* now=head;
            while(now!=NULL)
            {
                ListNode* next=now->next;
                now->next=last;
                last=now;
                now=next;
            }
            return last;
        }
    };
    leetcode 206

     牛客网 反转链表

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
    };*/
    class Solution {
    public:
        ListNode* start=nullptr;
        ListNode* now=start;
        void deal(ListNode* head)
        {
            if(head==nullptr)
                return;
            if(head->next==nullptr)
            {
                start=head;
                now=start;
                return ;
            }
            deal(head->next);
            now->next=head;
            now=now->next;
            now->next=nullptr;
            return;
        }
        ListNode* ReverseList(ListNode* pHead) {
            deal(pHead);
            return start;
        }
    };
    View Code

    leetcode 82. 删除排序链表中的重复元素 II

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* deleteDuplicates(ListNode* head)
        {
            struct ListNode* pass;
            struct ListNode* slow;
            struct ListNode* fast;
            if(head==NULL||head->next==NULL)
                return head;
            
            //处理头节点要删除的情况 递归删除
            int lables=0;
            while(head!=NULL&&head->next!=NULL&&head->val==head->next->val)
            {
                struct ListNode* tmp;
                tmp=head->next;
                head->next=tmp->next;
                delete tmp;
                lables=1;
            }
            if(lables==1)
            {
                head=head->next;
                head=deleteDuplicates(head);
            }
            if(head==NULL)
                return head;
            pass=head;
            if(pass==NULL||pass->next==NULL||pass->next->next==NULL)
                return head;
            slow=pass->next;
            fast=slow->next;
            if(slow->val==fast->val&&fast->next==NULL)
            {
                delete slow;
                delete fast;
                head->next=NULL;
                return head;
            }
            int lable=0;
            while(1)
            {
                if(fast==NULL&&lable==0)
                    return head;
                if(fast==NULL&&lable==1)
                {
                    pass->next=NULL;
                    return head;
                }    
                if(slow->val!=fast->val&&lable==0)//相邻不等
                {
                    pass=slow;
                    slow=fast;
                    fast=fast->next;
                    lable=0;
                    continue;
                }
                if(slow->val==fast->val)//slow=fast
                {
                    struct ListNode* tmp;
                    tmp=fast;
                    fast=fast->next;
                    delete tmp;
                    lable=1;
                    continue;
                }
                if(slow->val!=fast->val&&lable==1)//不相邻不相等
                {
                    pass->next=fast;
                    slow=fast;
                    fast=fast->next;
                    lable=0;
                    continue;
                }
            }
            return head;
        }
    };
    leetcode 82

    leetcode 面试题36. 二叉搜索树与双向链表

    要求做成双向循环链表

    class Solution {
    public:
        Node* start;
        Node* pre;
        Node* tail;
        void loop(Node* node)
        {
            if(node==NULL)
                return ;
            loop(node->left);
            if(pre==NULL)
                start=node;
            else
                pre->right=node;
            node->left=pre;
            pre=node;
            tail=node;
            loop(node->right);
            return ;
        }
        Node* treeToDoublyList(Node* root) {
            if(!root)
                return NULL;
            loop(root);
            start->left=tail;
            tail->right=start;
            return start;
        }
    };
    View Code

    牛客网二叉搜索树与双向链表 非循环链表 nullptr

    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };*/
    class Solution {
    public:
        TreeNode* start=nullptr;
        TreeNode* pre=nullptr;
        void loop(TreeNode* node)
        {
            if(node==nullptr)
                return ;
            loop(node->left);
            if(pre==nullptr)
                start=node;
            else
                pre->right=node;
            node->left=pre;
            pre=node;
            loop(node->right);
            return;
            
        }
        TreeNode* Convert(TreeNode* pRootOfTree)
        {
            loop(pRootOfTree);
            return start;
        }
    };
    View Code

    牛客网 链表中倒数第k个结点

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
    };*/
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            ListNode* fast;
            ListNode* slow;
            fast=pListHead;
            slow=pListHead;
            while(k--)
            {
                if(fast==nullptr)
                    return nullptr;
                fast=fast->next;
            }
            while(fast!=nullptr)
            {
                fast=fast->next;
                slow=slow->next;
            }
            return slow;
        }
    };
    View Code

    牛客网 合并两个有序链表

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
    };*/
    class Solution {
    public:
        ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
        {
            ListNode* start=new ListNode(-1);
            ListNode* out=start;
            while(pHead1&&pHead2)
            {
                if((pHead1->val)>(pHead2->val))
                {
                    out->next=pHead2;
                    pHead2=pHead2->next;
                }
                else
                {
                    out->next=pHead1;
                    pHead1=pHead1->next;
                }
                out=out->next;
            }
            out->next=(pHead1?pHead1:pHead2);
            return start->next;
        }
    };
    View Code

    leetcode 面试题26. 树的子结构        牛客网:树的子结构

    两次递归,注意比较一次失败以后还要继续比较可能正确答案在后面,leetcode的样例这里有漏洞

    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };*/
    class Solution {
    public:
        bool loop(TreeNode* tree1, TreeNode* tree2)
        {
            bool x1=false,x2=false;
            TreeNode* l1=tree1;
            TreeNode* l2=tree2;
            if(!l1&&l2)
                return false;
            if(!l2)
                return true;
            if(l1->val==l2->val)
            {
                x1=loop(l1->left,l2->left);
                x2=loop(l1->right,l2->right);
                return (x1&&x2);
            }
            else
                return false;
        }
        bool judge(TreeNode* tree1, TreeNode* tree2)
        {
            bool x=false,x1=false,x2=false;
            if(tree1==nullptr)
                return false;
            if(tree1->val==tree2->val)
            {
                x=loop(tree1,tree2);
            }
            x1=judge(tree1->left,tree2);
            x2=judge(tree1->right,tree2);
            if(x||x1||x2)
                return true;
            return false;
        }
        bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
        {
            if(pRoot2==nullptr)
                return false;
            return judge(pRoot1,pRoot2);
        }
    };
    View Code

    leetcode 面试题52. 两个链表的第一个公共节点       牛客网 两个链表的第一个公共结点

    第一个公共结点不是第一个键值相等的节点

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
    };*/
    class Solution {
    public:
        ListNode* FindFirstCommonNode( ListNode* headA, ListNode* headB) {
            ListNode *tmp_L1=headA;
            ListNode *tmp_L2=headB;
            int count1=1,count2=1;
            if(!tmp_L1||!tmp_L2)
                return NULL;
            while(tmp_L1->next!=nullptr)
            {
                tmp_L1=tmp_L1->next;
                count1++;
            }
            while(tmp_L2->next!=nullptr)
            {
                tmp_L2=tmp_L2->next;
                count2++;
            }
            if(count1>count2)
            {
                int tmp=count1-count2;
                while(tmp--)
                {
                    headA=headA->next;
                }
            }
            else if(count1<count2)
            {
                int tmp=count2-count1;
                while(tmp--)
                {
                    headB=headB->next;
                }
            }
            while(headA!=nullptr)
            {
                if(headA==headB)
                    return headA;
                headA=headA->next;
                headB=headB->next;
            }
            return nullptr;
        }
    };
    View Code

    leetcode 143. 重排链表

    思路是先遍历一遍找到链表的中心点(中心点往后的都需要插到前面去)。递归链表,链表返回的时候把返回的节点插到前面去,递归到中点就不插了。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* heads;
        int N;
        void deal(ListNode* node,int now)
        {
            if(node==nullptr)
                return ;
            deal(node->next,now+1);
            if(N>now||!heads||!heads->next)
                return;
            
            ListNode* tmp=heads->next;//
            heads->next=node;
            node->next=tmp;
            heads=tmp;
            if(tmp->next==node)//最后一个节点要断开
                tmp->next=nullptr;
            return;
        }
        void reorderList(ListNode* head) {
            ListNode* tmp=head;
            int count=0;
            while(tmp!=nullptr)
            {
                count++;
                tmp=tmp->next;
            }
            if(count%2==0)
                count/=2;
            else
                count=count/2+1;
            N=count;
            heads=head;
            deal(heads,1);
            return;
        }
    };
    leedcode 143
  • 相关阅读:
    中国剩余定理及拓展
    20191128-1 总结
    获取动态图
    弹球游戏设计
    作业要求 20191121-1 每周例行报告
    作业要求 20191114-1 每周例行报告
    对现组内成员的感谢
    作业要求 20191107-1 每周例行报告
    20191031-1 每周例行报告
    作业要求 20191024-1每周例行报告
  • 原文地址:https://www.cnblogs.com/dzzy/p/12311098.html
Copyright © 2020-2023  润新知