传统弱校HFUT的蒟蒻,真相只有一个

算法复习:链表

链表必须清楚掌握

链表定义

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

 

posted @ 2020-02-15 11:48  未名亚柳  阅读(229)  评论(0编辑  收藏  举报