C/C++每日一练(20230513) 二叉树专场(7)

news/2024/7/5 2:51:19

目录

1. 翻转二叉树  🌟

2. 二叉树的最小深度  🌟

3. 填充每个节点的下一个右侧节点指针  🌟🌟

附:二叉树的序列化与反序列化

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


1. 翻转二叉树

翻转一棵二叉树。

示例:

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

备注:
这个问题是受到 Max Howell 的 原问题启发的 :

谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。

出处:

https://edu.csdn.net/practice/27729560

代码:

#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
    TreeNode *invertTree(TreeNode *root)
    {
        if (!root)
        {
            return root;
        }
        TreeNode *temp = root->left;
        root->left = invertTree(root->right);
        root->right = invertTree(temp);
        return root;
    }
};

输出:


2. 二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

提示:

  • 树中节点数的范围在 [0, 105] 内
  • -1000 <= Node.val <= 1000

代码:

#include <bits/stdc++.h>
#define null INT_MIN
using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution
{
public:
    int minDepth(TreeNode *root)
    {
        if (!root)
            return 0;
        int left = minDepth(root->left);
        int right = minDepth(root->right);
        return (left && right) ? 1 + min(left, right) : 1 + left + right;
    }
};

TreeNode* buildTree(vector<int>& nums)
{
    TreeNode *root = new TreeNode(nums[0]);
    queue<TreeNode*> q;
    q.push(root);
    int i = 1;
    while(!q.empty() && i < nums.size())
    {
        TreeNode *cur = q.front();
        q.pop();
        if(nums[i] != null)
        {
            cur->left = new TreeNode(nums[i]);
            q.push(cur->left);
        }
        i++;
        if(i < nums.size() && nums[i] != null)
        {
            cur->right = new TreeNode(nums[i]);
            q.push(cur->right);
        }
        i++;
    }
    return root;
}

int main()
{
	Solution s;
	vector<int> root = {3,9,20,null,null,15,7};
	TreeNode* tree = buildTree(root);
	cout << s.minDepth(tree) << endl;
	
	root = {2,null,3,null,4,null,5,null,6};
	tree = buildTree(root);
	cout << s.minDepth(tree) << endl;

	return 0;
} 

输出:

2
5


3. 填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

进阶:

  • 你只能使用常量级额外空间。
  • 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

示例:

输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。

提示:

  • 树中节点的数量少于 4096
  • -1000 <= node.val <= 1000

出处:

https://edu.csdn.net/practice/27729558

代码:

#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
    int val;
    Node *left;
    Node *right;
    Node *next;
    Node() : val(0), left(NULL), right(NULL), next(NULL) {}
    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
    Node(int _val, Node *_left, Node *_right, Node *_next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
class Solution
{
public:
    Node *connect(Node *root)
    {
        if (!root)
            return nullptr;
        root->next = nullptr;
        connect_helper(root);
        return root;
    }
private:
    void connect_helper(Node *pNode)
    {
        if (!pNode)
            return;
        if (pNode->left == nullptr)
            return;
        pNode->left->next = pNode->right;
        if (pNode->right == nullptr)
            return;
        if (pNode->next != nullptr)
            pNode->right->next = pNode->next->left;
        else
            pNode->right->next = nullptr;
        connect_helper(pNode->left);
        connect_helper(pNode->right);
    }
};

输出:


附:二叉树的序列化与反序列化

class Codec
{
public:
    string serialize(TreeNode *root)
    {
        string result = "[";
        queue<TreeNode *> myQue;
        myQue.push(root);
        while (!myQue.empty())
        {
            root = myQue.front();
            myQue.pop();
            if (root == NULL)
            {
                result += "null,";
                continue;
            }
            else
            {
                result += to_string(root->val) + ",";
                myQue.push(root->left);
                myQue.push(root->right);
            }
        }
        if (result == "[null,")
        {
            result.resize(result.size() - 1);
        }
        else
        {
            int endIndex = result.size() - 1;
            while (result[endIndex] < '0' || result[endIndex] > '9')
            {
                endIndex -= 1;
            }
            result.resize(endIndex + 1);
        }
        result += "]";
        return result;
    }
    TreeNode *deserialize(string data)
    {
        vector<string> dataVec;
        int dataSize = data.size();
        for (int index = 1; index < dataSize - 1; ++index)
        {
            string tempData = "";
            while (index < dataSize - 1 && data[index] != ',')
            {
                tempData += data[index++];
            }
            dataVec.push_back(tempData);
        }
        int dataVecSize = dataVec.size();
        queue<TreeNode *> myQue;
        if (dataVec[0] == "null")
        {
            return NULL;
        }
        TreeNode *result = new TreeNode(atoi(dataVec[0].c_str())), *tempPtr;
        myQue.push(result);
        for (int index = 1; index < dataVecSize; ++index)
        {
            tempPtr = myQue.front();
            myQue.pop();
            if (dataVec[index] != "null")
            {
                tempPtr->left = new TreeNode(atoi(dataVec[index].c_str()));
                myQue.push(tempPtr->left);
            }
            index += 1;
            if (index < dataVecSize && dataVec[index] != "null")
            {
                tempPtr->right = new TreeNode(atoi(dataVec[index].c_str()));
                myQue.push(tempPtr->right);
            }
        }
        return result;
    }
};

🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.csdn.net/

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


http://lihuaxi.xjx100.cn/news/1126348.html

相关文章

数列合并C语言

已知两个不同长度的降序排列的数列&#xff08;假设序列的长度都不超过5&#xff09;&#xff0c;请编程将其合并为一个数列&#xff0c;使合并后的数列仍保持降序排列。 【提示】假设两个降序排列的数列分别保存在数组a和数组b中&#xff0c;用一个循环&#xff0c;从前往后依…

扩展你的Kubernetes集群:理解水平扩展与垂直扩展

这扩展你的Kubernetes集群&#xff1a;理解水平扩展与垂直扩展 一、前言1.1 什么是 Kubernetes1.2 扩展集群规模的必要性 二、集群规模扩展概述2.1 水平扩展 vs 垂直扩展2.2 Kubernetes 中的水平扩展2.3 节点的添加和删除 三、水平扩展实现方法3.1 使用 Deployment 扩展集群规模…

《Vue.js 设计与实现》—— 03 Vue.js 3 的设计思路

1. 声明式地描述 UI Vue.js 3 是一个声明式的 UI 框架&#xff0c;即用户在使用 Vue.js 3 开发页面时是声明式地描述 UI 的。 编写前端页面涉及的内容如下&#xff1a; DOM 元素&#xff1a;例如是 div 标签还是 a 标签属性&#xff1a;如 a 标签的 href 属性&#xff0c;再…

JQuery 详细教程

文章目录 一、JQuery 对象1.1 安装和使用1.2 JQuery包装集对象 二、JQuery 选择器2.1 基础选择器2.2 层次选择器2.3 表单选择器 三、JQuery Dom 操作3.1 操作元素3.1.1 操作属性3.1.2 操作样式3.1.3 操作内容 3.2 添加元素3.3 删除元素3.4 遍历元素 四、JQuery 事件4.1 ready 加…

MySQL笔记(四) 函数、变量、存储过程、游标、索引、存储引擎、数据库维护、指定字符集、锁机制

MySQL笔记&#xff08;四&#xff09; 文章目录 MySQL笔记&#xff08;四&#xff09;函数文本处理函数日期和时间处理函数数值处理函数类型转换函数流程控制函数自定义函数基本语法 局部变量全局变量聚集函数 aggregate functionDISTINCT 存储过程为什么要使用使用创建 删除建…

顺序表和链表的各种代码实现

一、线性表 在日常生活中&#xff0c;线性表的例子比比皆是。例如&#xff0c;26个英文字母的字母表&#xff08;A,B,C,……&#xff0c;Z&#xff09;是一个线性表&#xff0c;表中的数据元素式单个字母。在稍复杂的线性表中&#xff0c;一个数据元素可以包含若干个数据项。例…

进程与线程——嵌入式(驱动)软开基础(四)

1 异步IO和同步IO区别? 答案:如果是同步IO,当一个IO操作执行时,应用程序必须等待,直到此IO执行完。相反,异步IO操作在后台运行,IO操作和应用程序可以同时运行,提高系统性能,提高IO流量。 解读:在同步文件IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操…

如何在IVD行业运用IPD?

IVD&#xff08;体外诊断&#xff0c;In Vitro Diagnostic&#xff09;是指对人体样本&#xff08;血液、体液、组织&#xff09;进行定性或定量的检测&#xff0c;进而判断疾病或机体功能的诊断方法。IVD目前已经成为疾病预防、诊断治疗必不可少的医学手段&#xff0c;约80%左…