刷题 二叉树

news/2024/10/9 0:31:33 标签: c++

面试经典 150 题 - 二叉树

104. 二叉树的最大深度

在这里插入图片描述

广度优先遍历

class Solution {
public:
    // 广度优先遍历
    int maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        queue<TreeNode*> que;
        que.push(root);
        int result = 0;
        while (!que.empty()) {
            ++result;
            int num = que.size();
            while (num--) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
            }
        }
        return result;
    }
};

递归

最大深度 = 1 + max(左子树最大深度, 右子树最大深度)

class Solution {
public:
    // 递归:最大深度 = 1 + max(左子树最大深度, 右子树最大深度)
    int maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        return 1 + max(maxDepth(root->left), maxDepth(root->right));
    }
};

100. 相同的树

在这里插入图片描述

递归

树相同 --> 根节点相同 + 左子树相同 + 右子树相同

class Solution {
public:
    // 递归
    // 树相同 --> 根节点相同 + 左子树相同 + 右子树相同
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == nullptr && q == nullptr) {
            return true;
        } else if (p == nullptr || q == nullptr) {
            return false;
        }
        if (p->val != q->val) {
            return false;
        }
        if (isSameTree(p->left, q->left) == false) {
            return false;
        }
        if (isSameTree(p->right, q->right) == false) {
            return false;
        }
        return true;
    }
};

226. 翻转二叉树

在这里插入图片描述

递归

class Solution {
public:
    // 翻转二叉树 --> 
    // 根节点的左子树 = 将右子树进行反转
    // 根节点的右子树 = 将左子树进行反转
    TreeNode *invertTree(TreeNode *root) {
        if (root == nullptr) return nullptr;
        auto left = invertTree(root->left); // 翻转左子树
        auto right = invertTree(root->right); // 翻转右子树
        root->left = right; // 交换左右儿子
        root->right = left;
        return root;
    }
};

面试经典 150 题 - 二叉树层次遍历

199. 二叉树的右视图

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        if (root == nullptr) return vector<int>{};
        queue<TreeNode*> que;
        que.push(root);
        vector<int> result;
        while (!que.empty()) {
            size_t n = que.size();
            for (size_t i = 0; i < n; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
                if (i ==  n - 1) result.push_back(cur->val);
            }
        }
        return result;
    }
};

637. 二叉树的层平均值

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        if (root == nullptr) return vector<double>{};
        queue<TreeNode*> que;
        que.push(root);
        vector<double> result;
        while (!que.empty()) {
            size_t n = que.size();
            double sum = 0.0;
            for (size_t i = 0; i < n; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
                sum += cur->val;
            }
            result.push_back(sum / n);
        }
        return result;
    }
};

[102. 二叉树的层序遍历

](https://leetcode.cn/problems/binary-tree-level-order-traversal/?envType=study-plan-v2&envId=top-interview-150)

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if (root == nullptr) return vector<vector<int>>{};
        queue<TreeNode*> que;
        que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            size_t n = que.size();
            vector<int> layer(n, 0);
            for (size_t i = 0; i < n; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
                layer[i] = cur->val;
            }
            result.push_back(layer);
        }
        return result;
    }
};

103. 二叉树的锯齿形层序遍历 - 写入的时候改一下索引即可

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        if (root == nullptr) return vector<vector<int>>{};
        queue<TreeNode*> que;
        que.push(root);
        vector<vector<int>> result;
        bool to_right = false;
        while (!que.empty()) {
            to_right = !to_right;
            size_t n = que.size();
            vector<int> layer(n, 0);
            for (size_t i = 0; i < n; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
                if (to_right) {
                    layer[i] = cur->val;
                } else {
                    layer[n - 1 - i] = cur->val;
                }
            }
            result.push_back(layer);
        }
        return result;
    }
};

面试经典 150 题 - 二叉搜索树 - ⭐️TreeNode*& prev⭐️ - 中序遍历有序

98. 验证二叉搜索树

class Solution {
public:
    bool traversal(TreeNode* root, TreeNode*& prev) {
        if (root == nullptr) return true;
        if (!traversal(root->left, prev)) return false;
        if (prev != nullptr && prev->val >= root->val) return false;
        prev = root;
        return traversal(root->right, prev);
    }

    bool isValidBST(TreeNode* root) {
        TreeNode* prev = nullptr;
        return traversal(root, prev);
    }
};

530. 二叉搜索树的最小绝对差

在这里插入图片描述

使用数组暂存

class Solution {
public:
    // 二叉搜索树的特征:左子树 < 根节点 < 右子树
    // 中序遍历即可获得最小差值
    void traversal(TreeNode* root, vector<int>& vals, int& min_diff) {
        if (root == nullptr) return;
        traversal(root->left, vals, min_diff);
        if (!vals.empty()) min_diff = min(min_diff, root->val - vals.back()); 
        vals.push_back(root->val);
        traversal(root->right, vals, min_diff);
    }
    int getMinimumDifference(TreeNode* root) {
        vector<int> vals;
        int min_diff = INT_MAX;
        traversal(root, vals, min_diff);
        return min_diff;
    }
};

⭐️优化 - 使用一个 prev_val 即可

class Solution {
public:
    // 二叉搜索树的特征:左子树 < 根节点 < 右子树
    // 中序遍历即可获得最小差值
    // 如果不想使用数组暂存的话就需要存储一个 prev 指针
    void traversal(TreeNode* root, TreeNode*& prev, int& min_diff) {
        if (root == nullptr) return;
        traversal(root->left, prev, min_diff);
        if (prev != nullptr) min_diff = min(min_diff, root->val - prev->val); 
        prev = root;
        traversal(root->right, prev, min_diff);
    }
    int getMinimumDifference(TreeNode* root) {
        int min_diff = INT_MAX;
        TreeNode* prev = nullptr;
        traversal(root, prev, min_diff);
        return min_diff;
    }
};

230. 二叉搜索树中第 K 小的元素 - 想象用数组存储元素 - 实际只使用索引即可 - 注意终止条件

class Solution {
public:
    void traversal(TreeNode* root, int& val, int& count, int k) {
        if (root == nullptr || count >= k) return;  // 递归终止条件
        traversal(root->left, val, count, k);
        ++count;    // 如果用数组存储元素,想象这里是数组的第 count 个数字(从0开始)
        if (count == k) {
            val = root->val;
            return;
        }
        traversal(root->right, val, count, k);
    }
    int kthSmallest(TreeNode* root, int k) {
        int val, count = 0;
        traversal(root, val, count, k);
        return val;
    }
};

http://www.niftyadmin.cn/n/5695048.html

相关文章

C++ STL容器(五) —— priority_queue 底层剖析

这篇来讲下 priority_queue&#xff0c;其属于 STL 的容器适配器&#xff0c;容器适配器是在已有容器的基础上修改活泼限制某些数据接口以适应更特定的需求&#xff0c;比如 stack 栈使数据满足后进先出&#xff0c;queue 队列使数据满足先进先出&#xff0c;其都是在已有容器上…

c语言:二叉树的创建、前序遍历、中序遍历、后续遍历

代码中创建的二叉树如下图 013##4##25##6##代码&#xff1a; #include <stdio.h> #include <stdlib.h>typedef struct Tree{int value;struct Tree* lchild;struct Tree* rchild; } Tree;// 创建节点 Tree* Tree_createnode(int value){Tree* node (Tree* )mallo…

别再熬夜赶稿!AI自动成文插图,惊呆我了,效果如何?

今天试了下 Napkin 这个工具&#xff0c;发现简直是做自媒体专业文的写作神器&#xff0c;可以把已经准备好的文章快速配上数据图。 当然也可以一句简单的 prompt 生成文章&#xff0c;然后针对每一段可以生成对应的插图&#xff0c;还在在此基础上进一步调整&#xff0c;太牛了…

【Java 并发编程】多线程安全问题(上)

前言 虽然并发编程让我们的 CPU 核心能够得到充分的使用&#xff0c;程序运行效率更高效。但是也会引发一些问题。比如当进程中有多个并发线程进入一个重要数据的代码块时&#xff0c;在修改数据的过程中&#xff0c;很有可能引发线程安全问题&#xff0c;从而造成数据异常。 p…

『网络游戏』窗口基类【06】

创建脚本&#xff1a;WindowRoot.cs 编写脚本&#xff1a; 修改脚本&#xff1a;LoginWnd.cs 修改脚本&#xff1a;LoadingWnd.cs 修改脚本&#xff1a;ResSvc.cs 修改脚本&#xff1a;LoginSys.cs 运行项目 - 功能不变 本章结束

二维数组的旋转与翻转(C++)(上(这只是简单讲解))

二维数组的旋转与翻转&#xff08;C&#xff09; 引言 在计算机科学中&#xff0c;二维数组是一种常见的数据结构&#xff0c;广泛应用于图像处理、数据挖掘、机器学习等多个领域。二维数组的旋转与翻转是处理二维数据时经常需要用到的操作。本文将详细介绍二维数组的旋转与翻…

101 公司战略的基本概念

公司战略的概念 传统概念&#xff08;战略是终点途径&#xff09;&#xff1a;计划性、全局性、长期性现代概念&#xff08;战略是途径&#xff09;&#xff1a;应变性、竞争性、风险性综合概念&#xff08;前二者的折中&#xff09;&#xff1a;预先性、反应性公司的使命与目标…

Go语言实现长连接并发框架 - 请求分发器

文章目录 前言接口结构体接口实现项目地址最后 前言 你好&#xff0c;我是醉墨居士&#xff0c;我们上篇博客实现了任务管理器的功能&#xff0c;接下来这篇博客我们将要实现请求分发模块的开发 接口 trait/dispatcher.go type Dispatcher interface {Start()Dispatch(conn…