算法营day4

牛客 反转链表

思路1:
链表的长度总共有n项,假设第k+1到n项都反转完毕了,只需要更改第k+1的指针,让他指向第k项,然后让第k项指向空。
代码1:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* ReverseList(ListNode* pHead) {
    
    
        if(nullptr == pHead || nullptr == pHead->next) 
            return pHead;
        ListNode *p = ReverseList(pHead->next);
        pHead->next->next = pHead;
        pHead->next = nullptr;
        return p;
    }
};

思路2:
用三个指针,将当前节点的next指针指向前一个指针即可。用
代码2:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* ReverseList(ListNode* pHead) {
    
    
       //ListNode *ReverseHead = nullptr;//用来记住反转之后的链表的头结点
       ListNode *pNode = pHead;//用于指向当前节点
       ListNode* pPre = nullptr;//用于指向当前节点的前一个节点
       while(pNode != nullptr){
    
    
           //if(nullptr == pNode->next)
               //ReverseHead = pNode;
           ListNode* pNext = pNode->next;//用于指向当前节点的后一个,必须记住。
           pNode->next = pPre;
           pPre = pNode;
           pNode = pNext;
       }
        return pPre;
    }
};

牛客 合并两个排序的链表

题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路1:
见代码中的详细注释
代码2:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
    
    
        //处理特殊情况
        if(nullptr == pHead1)
            return pHead2;
        if(nullptr == pHead2)
            return pHead1;
        //合并后链表的头和尾
        ListNode *head = nullptr;
        ListNode *tail = nullptr;
        //pHead1和pHead2都不为空的情况
        while(pHead1 && pHead2){
    
    
            //获得较小的节点做为新插入的节点
            ListNode *p = pHead1->val < pHead2->val ? pHead1 : pHead2;
            //更新位置
            if(p == pHead1){
    
    
                pHead1 = pHead1->next;
            }
            else
                pHead2 = pHead2->next;
            //插入第一个结点的情况
            if(nullptr == head){
    
    
                head = p;
                tail = p;
            }
            //插入非第一个节点的情况
            else{
    
    
                tail->next = p;
                tail = p;
            }
        }
        //跳出while循环之后,处理其中的一个链表先结束的情况
        if(nullptr == pHead1)
            tail->next = pHead2;
        else
            tail->next = pHead1;
        //返回合成的新链表的头结点
        return head;
    }
};

思路2:
见代码详细注释
代码2:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
    
    
        //递归函数的出口
        if(nullptr == pHead1)
            return pHead2;
        if(nullptr == pHead2)
            return pHead1;
        //链表的新的头结点
        ListNode *head = pHead1->val < pHead2->val ? pHead1 : pHead2;
        //判断是从哪个链表截出来的节点,并更新
        if(head == pHead1)
            pHead1 = pHead1->next;
        else
            pHead2 = pHead2->next;
        //递归解决
        head->next = Merge(pHead1,pHead2);
        //返回最终的头结点
        return head;
    }
};

牛客 树的子结构

题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路1:
思路见代码注释
代码1:

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
    
    
public:
    bool isSame(TreeNode* begin, TreeNode* beginSub)
    {
    
    
        //递归出口,beginSub为空的话,说明全部找完了
        if(nullptr == beginSub){
    
    
            return true;
        }
        //begin为空的话,没有完全匹配,返回false
        if(nullptr == begin){
    
    
            return false;
        }
        //有不相等的情况就返回false
        if(begin->val != beginSub->val){
    
    
            return false;
        }
        //递归
        return isSame(begin->left,beginSub->left) &&
            isSame(begin->right, beginSub->right);
    }
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
    
    
        if(pRoot1 == nullptr || pRoot2 == nullptr)
            return false;
        bool result = false;
        //先找起始位置
        if(pRoot1->val == pRoot2->val){
    
    
            //判断它的左子树和右子树是否相等,调用函数判断
            result = isSame(pRoot1, pRoot2);
        }
        //在左子树中找
        if(!result){
    
    
            result = HasSubtree(pRoot1->left, pRoot2);
        }
        //在右子树中找
        if(!result){
    
    
            result = HasSubtree(pRoot1->right, pRoot2);
        }
        return result;
    }
};

牛客 二叉树的镜像

题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。

思路:
二叉树镜像本质是自顶向下进行左右子树交换的过程
代码:

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
    
    
public:
    void Mirror(TreeNode *pRoot) {
    
    
        if(nullptr == pRoot)
            return ; 
        TreeNode *temp = pRoot->left;
        pRoot->left = pRoot->right;
        pRoot->right = temp;
        Mirror(pRoot->left);
        Mirror(pRoot->right);
    }
};

猜你喜欢

转载自blog.csdn.net/qq_35353824/article/details/107537411