草庐IT

C/C++每日一练(20230326) 二叉树专场(3)

Hann Yang 2023-04-14 原文

目录

1. 二叉树的前序遍历  🌟🌟

2. 二叉树的最大深度  🌟

3. 有序数组转换为二叉搜索树  🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


1. 二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

输入:root = [1,2]
输出:[1,2]

示例 5:

输入:root = [1,null,2]
输出:[1,2]

提示:

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

进阶:递归算法很简单,你可以通过迭代算法完成吗?

出处:

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

代码: 递归算法

#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

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

class Solution
{
private:
    void rec(TreeNode *root, vector<int> &ret)
    {
        if (root != nullptr)
        {
            ret.push_back(root->val);
            rec(root->right, ret);
            rec(root->left, ret);
        }
    }
public:
    vector<int> postorderTraversal(TreeNode *root)
    {
        vector<int> ret;
        rec(root, ret);
        return ret;
    }
};

string Vector2String(vector<int> vect) {
    stringstream ss;
	ss << "[";
    for (size_t i = 0; i < vect.size(); i++)
	{
        ss << to_string(vect[i]);
        ss << (i < vect.size() - 1 ? "," : "]");
    }
    return ss.str();
}

int main()
{
    TreeNode *root = new TreeNode(1);
    root->right = new TreeNode(2);
    root->right->left = new TreeNode(3);
    Solution s;
	cout << Vector2String(s.postorderTraversal(root)) << endl;
    
    return 0;
}

输出:

[2,1,3]

进阶: 迭代算法

#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#define null INT_MIN
using namespace std;

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

TreeNode* buildTree(vector<int>& nums)
{
    if (nums.empty()) return nullptr;
	TreeNode *root = new TreeNode(nums.front());
    queue<TreeNode*> q;
    q.push(root);
    int i = 1;
    while(!q.empty() && i < nums.size())
    {
        TreeNode *cur = q.front();
        q.pop();
        if(i < nums.size() && 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;
}

void preorderPrint(TreeNode* root) {
    stack<TreeNode*> st;
    st.push(root);
    while (!st.empty()) {
        TreeNode* node = st.top();
        st.pop();
        if (node != nullptr) {
            cout << node->val << " ";
            st.push(node->right);
            st.push(node->left);
        }
    }
    cout << endl;
}

void preorderPrint2(TreeNode* root) {
    stack<TreeNode*> st;
    TreeNode* node = root;
    while (node != nullptr || !st.empty()) {
        while (node != nullptr) {
            cout << node->val << " ";
            st.push(node);
            node = node->left;
        }
        node = st.top();
        st.pop();
        node = node->right;
    }
    cout << endl;
}

vector<int> preorderTraversal(TreeNode* root) {
    vector<int> res;
    stack<TreeNode*> st;
    st.push(root);
    while (!st.empty()) {
        TreeNode* node = st.top();
        st.pop();
        if (node != nullptr) {
            res.push_back(node->val);
            st.push(node->right);
            st.push(node->left);
        }
    }
    return res;
}

vector<int> preorderTraversal2(TreeNode* root) {
    vector<int> res;
    stack<TreeNode*> st;
    TreeNode* node = root;
    while (node != nullptr || !st.empty()) {
        while (node != nullptr) {
            res.push_back(node->val);
            st.push(node);
            node = node->left;
        }
        node = st.top();
        st.pop();
        node = node->right;
    }
    return res;
}

string vectorToString(vector<int> vect) {
    stringstream ss;
	ss << "[";
    for (size_t i = 0; i < vect.size(); i++)
	{
        ss << (vect[i] == null ? "null" : to_string(vect[i]));
        ss << (i < vect.size() - 1 ? "," : "]");
    }
    return ss.str();
}

int main()
{
	vector<int> nums = {1,null,2,3};
    TreeNode *root = buildTree(nums);
    preorderPrint(root);
    preorderPrint2(root);
	cout << vectorToString(preorderTraversal(root)) << endl;
	cout << vectorToString(preorderTraversal2(root)) << endl;
    
	nums = {3,9,20,null,null,15,7};
    root = buildTree(nums);
    preorderPrint(root);
    preorderPrint2(root);
	cout << vectorToString(preorderTraversal(root)) << endl;
 	cout << vectorToString(preorderTraversal2(root)) << endl;
    
	nums = {1,2,3,4,5,6,7};
    root = buildTree(nums);
    preorderPrint(root);
    preorderPrint2(root);
	cout << vectorToString(preorderTraversal(root)) << endl;
	cout << vectorToString(preorderTraversal2(root)) << endl;
    
    return 0;
}

输出:

1 2 3
1 2 3
[1,2,3]
[1,2,3]
3 9 20 15 7
3 9 20 15 7
[3,9,20,15,7]
[3,9,20,15,7]
1 2 4 5 3 6 7
1 2 4 5 3 6 7
[1,2,4,5,3,6,7]
[1,2,4,5,3,6,7]

中序后序对比:

//中序遍历
void inorder(TreeNode* root) {
    stack<TreeNode*> st;
    TreeNode* node = root;
    while (!st.empty() || node != nullptr) {
        while (node != nullptr) {
            st.push(node);
            node = node->left;
        }
        node = st.top();
        st.pop();
        cout << node->val << " ";
        node = node->right;
    }
}

//后序遍历
void postorder(TreeNode* root) {
    stack<TreeNode*> st;
    TreeNode* node = root;
    TreeNode* last = nullptr;
    while (!st.empty() || node != nullptr) {
        while (node != nullptr) {
            st.push(node);
            node = node->left;
        }
        node = st.top();
        if (node->right == nullptr || node->right == last) {
            cout << node->val << " ";
            st.pop();
            last = node;
            node = nullptr;
        } else {
            node = node->right;
        }
    }
}

2. 二叉树的最大深度

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

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

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

示例:
给定二叉树 [3,9,20,null,null,15,7]

     3
    / \
   9  20
 /  \
15   7

返回它的最大深度 3 。

出处:

https://bbs.csdn.net/topics/604364348

代码:

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#define null INT_MIN
using namespace std;

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

class Solution
{
public:
	int maxDepth(TreeNode* root) {
	    if (!root) return 0;
	    stack<pair<TreeNode*, int>> s;
	    int maxDep = 0;
	    s.push(make_pair(root, 1));
	    while (!s.empty()) {
	        TreeNode* cur = s.top().first;
	        int curDep = s.top().second;
	        s.pop();
	        if (cur) {
	            maxDep = max(maxDep, curDep); 
	            s.push(make_pair(cur->left, curDep + 1));
	            s.push(make_pair(cur->right, curDep + 1));
	        }
	    }
	    return maxDep;
	}
};

TreeNode* buildTree(vector<int>& nums)
{
    if (nums.empty()) return nullptr;
	TreeNode *root = new TreeNode(nums.front());
    queue<TreeNode*> q;
    q.push(root);
    int i = 1;
    while(!q.empty() && i < nums.size())
    {
        TreeNode *cur = q.front();
        q.pop();
        if(i < nums.size() && 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> nums = {3,9,20,null,null,15,7};
    TreeNode *root = buildTree(nums);
	cout << s.maxDepth(root) << endl;

	nums = {1,null,2,null,3,null,4};
    root = buildTree(nums);
	cout << s.maxDepth(root) << endl;

    return 0;
}

输出:

3
4

递归法:

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#define null INT_MIN
using namespace std;

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

class Solution
{
public:
	int maxDepth(TreeNode* root) {
	    if (!root) return 0; 
	    int ldepth = maxDepth(root->left);
	    int rdepth = maxDepth(root->right);
	    return max(ldepth, rdepth) + 1;
	}
};

TreeNode* buildTree(vector<int>& nums)
{
    if (nums.empty()) return nullptr;
	TreeNode *root = new TreeNode(nums.front());
    queue<TreeNode*> q;
    q.push(root);
    int i = 1;
    while(!q.empty() && i < nums.size())
    {
        TreeNode *cur = q.front();
        q.pop();
        if(i < nums.size() && 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> nums = {3,9,20,null,null,15,7};
    TreeNode *root = buildTree(nums);
	cout << s.maxDepth(root) << endl;

	nums = {1,null,2,null,3,null,4};
    root = buildTree(nums);
	cout << s.maxDepth(root) << endl;

    return 0;
}

3. 有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:

  • 1 <= nums.length <= 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums 按 严格递增 顺序排列

出处:

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

代码:

#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#define null INT_MIN
using namespace std;

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

class Solution
{
public:
    TreeNode *sortedArrayToBST(vector<int> &nums)
    {
        return dfs(nums, 0, nums.size() - 1);
    }
    TreeNode *dfs(vector<int> &nums, int left, int right)
    {
        if (left > right)
            return NULL;
        int mid = (left + right) / 2;
        TreeNode *t = new TreeNode(nums[mid]);
        t->left = dfs(nums, left, mid - 1);
        t->right = dfs(nums, mid + 1, right);
        return t;
    }
};

vector<int> levelOrder(TreeNode* root) {
    vector<int> res;
    if (!root) return res;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        TreeNode* cur = q.front();
        q.pop();
        if (cur) {
            res.push_back(cur->val); 
            q.push(cur->left);
            q.push(cur->right);
        } else {
            res.push_back(null);
        }
    }
    for(int i = res.size(); i > 0 && res[i-1] == null; i--)
    	res.pop_back();
    return res;
}

string vectorToString(vector<int> vect) {
    stringstream ss;
	ss << "[";
    for (size_t i = 0; i < vect.size(); i++)
	{
        ss << (vect[i] == null ? "null" : to_string(vect[i]));
        ss << (i < vect.size() - 1 ? "," : "]");
    }
    return ss.str();
}

int main()
{
    Solution s;
	vector<int> nums = {-10,-3,0,5,9};
    TreeNode *bst = s.sortedArrayToBST(nums);
	cout << vectorToString(levelOrder(bst)) << endl;

	nums = {1,3};
    bst = s.sortedArrayToBST(nums);
	cout << vectorToString(levelOrder(bst)) << endl;

    return 0;
}

输出:

[0,-10,5,null,-3,null,9]
[1,null,3]

代码2:

#include <iostream>
#include <sstream>
#include <vector>
#include <queue>
#define null INT_MIN
using namespace std;

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

class Solution
{
public:
	TreeNode* sortedArrayToBST(vector<int>& nums) {
	    if (nums.empty()) return nullptr;
	    int mid = nums.size() / 2;
	    TreeNode* root = new TreeNode(nums[mid]);
	    vector<int> left(nums.begin(), nums.begin() + mid);
	    vector<int> right(nums.begin() + mid + 1, nums.end());
	    root->left = sortedArrayToBST(left);
	    root->right = sortedArrayToBST(right);
	    return root;
	}
};

vector<int> levelOrder(TreeNode* root) {
    vector<int> res;
    if (!root) return res;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        TreeNode* cur = q.front();
        q.pop();
        if (cur) {
            res.push_back(cur->val); 
            q.push(cur->left);
            q.push(cur->right);
        } else {
            res.push_back(null);
        }
    }
    for(int i = res.size(); i > 0 && res[i-1] == null; i--)
    	res.pop_back();
    return res;
}

string vectorToString(vector<int> vect) {
    stringstream ss;
	ss << "[";
    for (size_t i = 0; i < vect.size(); i++)
	{
        ss << (vect[i] == null ? "null" : to_string(vect[i]));
        ss << (i < vect.size() - 1 ? "," : "]");
    }
    return ss.str();
}

int main()
{
    Solution s;
	vector<int> nums = {-10,-3,0,5,9};
    TreeNode *bst = s.sortedArrayToBST(nums);
	cout << vectorToString(levelOrder(bst)) << endl;

	nums = {1,3};
    bst = s.sortedArrayToBST(nums);
	cout << vectorToString(levelOrder(bst)) << endl;

    return 0;
}

输出:

[0,-3,9,-10,null,5]
[3,1]


🌟 每日一练刷题专栏 🌟

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

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

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

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

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

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏

有关C/C++每日一练(20230326) 二叉树专场(3)的更多相关文章

  1. ruby - 在 Ruby 中实现二叉树 - 2

    我一直在尝试在Ruby中实现BinaryTree类,但我得到了stackleveltoodeep错误,尽管我似乎没有在该特定代码段中使用任何递归:1.classBinaryTree2.includeEnumerable3.4.attr_accessor:value5.6.definitialize(value=nil)7.@value=value8.@left=BinaryTree.new#stackleveltoodeephere9.@right=BinaryTree.new#andhere10.end11.12.defempty?13.(self.value==nil)?true:

  2. 蓝桥杯C/C++VIP试题每日一练之报时助手 - 2

    ?作者主页:静Yu?简介:CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家,前端知识交流社区创建者?社区地址:前端知识交流社区?博主的个人博客:静Yu的个人博客?博主的个人笔记本:前端面试题个人笔记本只记录前端领域的面试题目,项目总结,面试技巧等等。接下来会更新蓝桥杯官方系统基础练习的VIP试题,依然包括解题思路,源代码等等。问题描述:给定当前的时间,请用英文的读法将它读出来。时间用时h和分m表示,在英文的读法中,读一个时间的方法是:  如果m为0,则将时读出来,然后加上“o’clock”,如3:00读作“threeo’clock”。  如果m不为0,则将时读出来,然后将分读出来,如5

  3. Python:每日一题之小张的衣服(优先队列、哈夫曼编码) - 2

    题目描述小张买了 n 件白色的衣服,他觉得所有衣服都是一种颜色太单调,希望对这些衣服进行染色,每次染色时,他会将某种颜色的所有衣服寄去染色厂,第 i 件衣服的邮费为 ai​ 元,染色厂会按照小张的要求将其中一部分衣服染成同一种任意的颜色,之后将衣服寄给小张,请问小张要将 n 件衣服染成不同颜色的最小代价是多少?输入描述第一行为一个整数 n ,表示衣服的数量。第二行包括 n 个整数a1​,a2​...an​ 表示第 i 件衣服的邮费为 ai​ 元。(1≤n≤10^5,1≤ai​≤10^9 )输出描述输出一个整数表示小张所要花费的最小代价。输入输出样例输入551321输出25 思考🤔:题意:意思是

  4. C++---最长上升子序列模型---最大上升子序列和(每日一道算法2023.3.3) - 2

    注意事项:本题为"线性dp—最长上升子序列的长度"的扩展题,所以dp思路这里就不再赘述。题目:比如,对于序列(1,7,3,5,9,4,8),有它的一些上升子序列,如(1,7),(3,4,8)等。这些子序列中和最大为18,为子序列(1,3,5,9)的和。你的任务,就是对于给定的序列,求出最大上升子序列和。注意,最长的上升子序列的和不一定是最大的,比如序列(100,1,2,3)的最大上升子序列和为100,而最长上升子序列为(1,2,3)。输入格式输入的第一行是序列的长度N。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000(可能重复)。输出格式输出一个整数,表示最大上升子序列和。数据

  5. 牛客竞赛每日俩题 - 动态规划3 - 2

    目录类01背包问题,选or不选变种走方格类01背包问题,选or不选不同的子序列_牛客题霸_牛客网问题翻译:        S有多少个不同的子串与T相同        S[1:m]中的子串与T[1:n]相同的个数        由S的前m个字符组成的子串与T的前n个字符相同的个数状态:        子状态:由S的前1,2,...,m个字符组成的子串与T的前1,2,...,n个字符相同的个数        F(i,j):S[1:i]中的子串与T[1:j]相同的个数状态递推:        在F(i,j)处需要考虑S[i]=T[j]和S[i]!=T[j]两种情况        当S[i]=T[j]

  6. ​ 【蓝桥杯】每日四道编程题(两道真题+两道模拟)​| 第6天 - 2

    专栏: 蓝桥杯——每日四道编程题(两道真题+两道模拟)“蓝桥杯就要开始了,这些题刷到就是赚到”₍ᐢ..ᐢ₎♡另一个专栏: 蓝桥杯——每日四道填空题(两道真题+两道模拟题)专题前瞻:复习并查集、Tire字符串、双指针、二分目录第一道真题(日志统计)输出描述输入输出样例第二道真题(合根植物)输出描述输入输出样例第三道模拟题(acwing):Trie字符串统计第四道真题(扫地机器人)题目描述第一道真题(日志统计) 输出描述按从小到大的顺序输出热帖 id。每个 id 一行。输入输出样例输入:71020101010101019110031003输出;13运行限制最大运行时间:1s最大运行内存:256M双

  7. 【蓝桥杯】每日四道填空题(两道真题+两道模拟题)| 第四天 - 2

    专栏:蓝桥杯——每日四道填空题(两道真题+两道模拟题)&离蓝桥杯已经不到一个月时间了,赶快刷起来吧,填空题一定别丢分!!୧꒰•̀ᴗ•́꒱୨另一个专栏是:蓝桥杯——编程题刷题营(每日四题,两道模拟,两道真题)目录第一道真题(2016年省赛):寒假作业 |答案:64第二道真题(2019年省赛):质数 |答案:17569第三道模拟题(2022年第二次模拟赛): 拆分质数个数|答案:33第四道模拟题():答案:10第一道真题(2016年省赛):寒假作业 |答案:64题目描述本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。现在小学的数学题目也不是那么好玩的。看看这个寒假作业:  

  8. javascript - 与二维碰撞有关的四叉树 - 2

    我一直在研究这个:https://github.com/mikechambers/ExamplesByMesh/blob/master/JavaScript/QuadTree/src/QuadTree.js我相信我理解四叉树的一般概念,尽管我对它们的工作原理和上面的实现有两个问题:难道你不需要每隔几毫秒重建整个树吗?在Javascript中,这不会非常慢吗?如果我有这样的东西:http://davzy.com/screenshots/skitched-20120318-180324.png,那么很容易找到同一个四边形中的其他点,但我有一个矩形与3个不同的四边形相交,有没有办法让它显示为

  9. 【C语言每日亿题】运算符专练 · 第4日 - 2

    🌕写在前面Hello🤗大家好啊,我是kikokingzz,名字太长不好记,大家可以叫我kiko哦~从今天开始,我将正式开启一个新的打卡专题——《C语言百炼成神计划》,没错!百炼成神,目的是通过百天刷题计划,通过题目和知识点串联的方式,完成C语言的复习和巩固;后期还会配有专门的笔记总结和文档教程哦!想要搞定,搞透C语言的同学🎉🎉欢迎持续关注🎉🎉🍊博客主页:kikoking的江湖背景🍊🌟🌟往期必看🌟🌟🔥【C语言百炼成神】第一日·操作符🔥🔥【C语言百炼成神】第二日·操作符🔥🔥【C语言百炼成神】第三日·操作符🔥ps:文章若有任何疑问欢迎光速评论私信我!!有时kiko可能会打错,脑子瓦特了😵‍💫目录🌕写

  10. 利用腾讯云函数实现和鲸社区每日自动登录 - 2

    和鲸社区算是国内比较不错的机器学习算力平台,可以通过每日登录积累成长值,每月还会给鲸币奖励,有一段时间每天都会登登陆一次,但是有时候还是会忘记。最近根据腾讯云Serverless部署云函数实现自动登录,解放双手。首先每次登陆后将进行微信推送,我采用的是pushplus平台,获取token即可。微信推送#从pushplus平台获取tokentoken='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'defsendToWechat(title,content):url='http://www.pushplus.plus/send'headers={'Content-Type

随机推荐