C++刷题笔记:树

CCF 201809-3 2018年9月第三题元素选择器(C++ 100分题解) CCF 201809-3 2018年9月第三题元素选择器(C++ 100分题解) 试题编号: 3 试题名称: 元素选择器 时间限制: 10.0s 内存限制: 512.0MB 提交后100分代码: 这道题本身很简单,但是我刚做的时候很多东西都不会,正好借这个题目学习了很多。 第一,对于字符串的处理,要用到stringstream进行分词,可以用正则表达式进行匹配; 第二,数据结构,这其实就是一个简... 阅读详情


前序/中序/后序遍历

求后序遍历

参考 根据前序遍历和中序遍历求后序遍历

已知前序遍历abdgcefh,中序遍历dgbaechf

在这里插入图片描述
根据前序确定根节点,根据中序确定子序列。再在子序列中确定父节点,以此类推。

那么,后序遍历为:gdbehfca

递归法

void inorder_traversal_dfs(TreeNode *root, vector<int> &ret) {
    if (root == nullptr) return;
    inorder_traversal_dfs(root->left, ret);
    ret.push_back(root->val);
    inorder_traversal_dfs(root->right, ret);
}

vector<int> inorder_traversal(TreeNode *root) {
    vector<int> ret;
    inorder_traversal_dfs(root, ret);
    return ret;
}

迭代法

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

迭代法层序遍历

广度优先搜索算法 BFS:手动维护一个队列,先把根节点入队,每次出队之前,把非空的左右子结点入队。题解自 https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
在这里插入图片描述

vector<vector<int>> level_order(TreeNode *root) {
    vector<vector<int>> results;
    if (!root) 	return results;
    
    queue<TreeNode *> q;
    q.push(root);
    while (!q.empty()) {
        int n = q.size();
        vector<int> level(n);
        for (int i = 0; i < n; i++) {
            level[i] = q.front()->val;
            if (q.front()->left) q.push(q.front()->left);
            if (q.front()->right) q.push(q.front()->right);
            q.pop();
        }
        results.push_back(level);
    }
    return results;
}

求树的深度

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

class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
         if(pRoot == NULL) return 0;
         return max(TreeDepth(pRoot->left), TreeDepth(pRoot->right)) + 1;
    }
};

判断平衡二叉树

输入一棵二叉树,判断该二叉树是否是平衡二叉树。在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树。

class Solution {
public:
    int depth(TreeNode *root) {
        if (!root) return 0;		// 空树也是平衡树
        
        int l = depth(root->left);   // 提前截止
        if (l == -1) return -1;
        
        int r = depth(root->right);  // 提前截止
        if (r == -1) return -1;
        
        if (abs(l - r)> 1) return -1;
        return max(l, r) + 1;
    }
    bool IsBalanced_Solution(TreeNode* root) {
        return depth(root) != -1;
    }
};

重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

思路:

  • 递归截止:子树序列中无结点
  • 由前序序列确定根结点
  • 在中序序列中根据root的索引,分为左右子树
  • 分别递归左子树和右子树
  • 返回根节点
    在这里插入图片描述
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        // 递归求解
        return reconstruct(pre, 0, pre.size(), vin, 0, vin.size());
    }
    
    TreeNode* reconstruct(vector<int>& pre, int pl, int pr, 
                          vector<int>& vin, int vl, int vr){
        // 前序没有结点时,迭代终止
        if(pl==pr) return nullptr;
        // 根节点
        TreeNode* root = new TreeNode(pre[pl]);
        // 确定中序遍历中根节点的索引,分为左右子树,进行递归
        for(int i=vl; i<vr; ++i){
            if(vin[i] == root->val){
                int num = i - vl; // 左子树的结点个数
                root->left = reconstruct(pre, pl+1, pl+1+num, vin, vl, i);
                root->right = reconstruct(pre, pl+1+num, pr, vin, i+1, vr);
                break;
            }
        }
        return root;
    }
};

滑动窗口最大值

题目描述:
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

分析:
可以用暴力遍历的方法,时间复杂度:O(n*k), 其中n为数组大小,k为窗口大小。也可以用平衡二叉树或完全二叉树(大顶堆),这里只做试验:

平衡二叉树 map 自动排序,从小到大:将每个窗口的数据存入,删除老数据,存入新数据,读出最大的即可。

vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
    if (num.size() == 0 || size <= 0 || num.size() < size) return {};
    vector<int> ret;
    map<int, int> win;  // 元素:索引
    for (int i = 0; i < num.size(); ++i) {
        if (win.size() < size) {
            win[num[i]] = i;
            if (size == win.size()) {
                ret.push_back(win.rbegin()->first);
            }
        }
        else {
            win.erase(num[i - size]);
            win[num[i]] = i;
            ret.push_back(win.rbegin()->first);
        }
    }
    return ret;
}

数据流的中位数

题目描述:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

分析:
(1) 最简单的:每次插入vector,取中位数时排序 std::sort( v.begin(), v.end() );
(2) 插入的同时,进行排序:low_bound

class Solution2 {
public:
    void Insert(int num)
    {
        if (arr.empty()) arr.push_back(num);
        else {
            auto it = lower_bound(arr.begin(), arr.end(), num); // lower/upper都适用
            arr.insert(it, num);
        }
    }

    double GetMedian()
    {
        int n = arr.size();
        return n & 1 ? arr[n / 2] : (arr[n / 2 - 1] + arr[n / 2]) * 0.5;
    }

private:
    vector<int> arr;
};

注意:(n>>2) - 1 移位运算符的优先级低于算术运算符!!!判断奇偶可以用位运算符

(3) 利用优先队列:大顶堆+小顶堆

// 大顶堆,用来存放中位数的较小数 lows
// 小顶堆,用来存放中位数的较大数 ups

  • 最开始都是空堆,属于平衡状态
  • lows中存进一个数,就要转给ups一个
  • 如果 lows.size() < ups.size() 说明转多了,要补回来
class Solution3 {
public:
    void Insert(int num)
    {
        lows.emplace(num);
        ups.emplace(lows.top());
        lows.pop();

        if (lows.size() < ups.size()) {
            lows.emplace(ups.top());
            ups.pop();
        }
    }

    double GetMedian()
    {
        return lows.size() > ups.size() ? lows.top() : (lows.top() + ups.top()) * 0.5;
    }

private:
    priority_queue<int> lows;// 大顶堆,用来存放中位数的较小数
    priority_queue<int, vector<int>, greater<int>> ups;  // 小顶堆,用来存放中位数的较大数
};

寻找第K个结点

题目描述:
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

分析:
这题比较难。二叉搜索树的中序遍历就是将结点从小到大排序,所以第1小的结点就是遍历左子树,一直到空。想到的就是递归,遍历到叶子结点后,第i次回溯就是第i小的结点,这时要考虑右子树。

增序: 1 2 3 4
降序: 4 3 2 1
所以找第k小,就是找 k-- == 1

class Solution {
public:
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        this->k = k;
        dfs(pRoot);
        return node;
    }
    
    void dfs(TreeNode* p){
        // 节点不存在或已经找到则返回
        if(!p || k<1) return;
        
        // 继续寻找左子树
        dfs(p->left);
        
        // 回溯
        if(k==1) node = p;
        k--;
        if(p->right)  dfs(p->right);  
    }
    
private:
    TreeNode* node = nullptr;
    int k = 1;
};

判断二叉树是否镜像

class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot){
        return isSame(pRoot, pRoot);
    }
    
    bool isSame(TreeNode* r1, TreeNode* r2){
        if(!r1 && !r2) return true;			// 结点同时不存在
        if(!r1 || !r2) return false;		// 结点只存在一个
        return r1->val == r2->val 			// 结点同时都存在
            && isSame(r1->left, r2->right) 
            && isSame(r2->left, r1->right);
    }

};
真的神了~无意中发现1500道的2021LeetCode算法刷题pdf笔记 昨晚逛GitHub,无意中看到一位大佬的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙伴没有看到。 关于算法刷题的困惑和疑问也经常听朋友们提及。这份笔记里面共包含作者刷力扣算法题后整理的上千道题,每道题均附有详细题解过程。有了这个笔记的总结,对校招和社招的算法刷题帮助之大不言而喻,果断收藏安利。 累计1500+道...拿来即刷!word很大,你忍一下,我就不一一截图了,诸君自行下载哈。 可以看到,每道题的原题,题目大意,解题思路,以及代码实现都非常 阅读详情

相关推荐

C++刷题秘籍

C++刷题秘籍 在经过一个暑假的刷题过程中(只刷了pat乙级和洛谷新手村),总结了一下一些很有用的知识和函数,了解这些可以再刷题的时候避免自己写一大堆不必要的代码,在做题的时候节省时间。不同的函数也可以开阔自己的解题思路,从而更快想出最佳的解答方法。如果有在用C++进行刷题的小伙伴可以看看。不足的地方也希望大家能够指出来,一起学习一起进步。 1、为什么用C++ C++的好处在于它和C语言一样是比较...

qq_42832874的博客 2103

(每日一练c++)二叉树展开为链表

二叉树展开为链表 给你二叉树的根结点root,请你将它展开为一个单链表: 展开后的单链表应该同样使用TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。 展开后的单链表应该与二叉树先序遍历(https://baike.baidu.com/item/%E5%85%88%E5%BA%8F%E9%81%8D%E5%8E%86/6442839?fr=aladdin)顺序相同。 示例 1: 输入:root = [1,2,5,3,4,null,6]...

biyesheji1000的专栏 2466

刷题笔记C++

1231231263

weixin_43398741的博客 4056

[C/C++]二叉树基础

二叉树遍历与恢复

qq_41221520的博客 540

C++实现树(带完整源码)

本文实现的二叉树相对比较简单,但其应用广泛,有很多相关的算法和数据结构都是以树为基础而设计。在实际编程中,我们也可以通过对树的深度遍历(前序、中序、后序遍历等)和广度遍历(层次遍历)来解决一些实际问题。其中最基础的树型结构是二叉树,但也有更复杂的树形结构,如红黑树、B树等等。可以看到,我们创建了一个空根节点root,并将一个有9个元素的数组依次插入到二叉树中。需要注意的是,在定义struct时加上了一个构造函数,用来初始化节点的值。否则,比较新节点的值和根节点的值大小,递归地插入到左子树或者右子树。

TechRoarX的博客 398

c_c++刷题必备好资料

刷题中特别适合用的东西,自己总结的在做各种OJ题目时特别适合用

C++ 二叉树的构建及使用

C++中二叉树的构建及使用: 二叉树的构建: 代码: struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; struct TreeNode() :left(nullptr), right(nullptr) {} }; 二叉树的初始化: 代码: TreeNode* creatTreeNode(TreeNode* root, int val) { if (root == nullptr) {

jump 3513

c++算法刷题笔记.pdf

算法学习

每日刷题计划Day2笔记-字符串+树

题源:acwing A + B 格式 计算 a+b 并以标准格式输出总和----也就是说,从最低位开始每隔三位数加进一个逗号(千位分隔符),如果结果少于四位则不需添加。 输入格式 共一行,包含两个整数 a 和 b。 输出格式 共一行,以标准格式输出 a+b 的和。 数据范围 −106≤a,b≤106 输入样例: -1000000 9 输出样例: -999,991 #include <iostream> using namespace std; int main(){ int

布屿 974

ESP32-S3开发环境避坑指南:VS Code+ESP-IDF离线安装全流程(附国内镜像加速)

本文提供了一份详细的ESP32-S3开发环境离线安装指南,重点解决网络依赖问题。通过整合国内镜像加速,手把手教你完成VS Code、ESP-IDF框架、工具链及Python依赖的本地化部署,实现稳定、可重复的开发环境搭建,大幅提升IoT开发效率。

peach的博客 961

手把手教你用ADIsimCLK和GUI搞定HMC7044时钟配置(附避坑指南)

本文详细解析了HMC7044时钟芯片的配置方法,通过ADIsimCLK和HMC7044 Configuration GUI工具,从频率规划到硬件验证全流程实战演示。特别针对PLL模式选择、分频链配置等易错环节,提供量产验证的配置模板和实测数据,帮助工程师快速掌握高性能时钟解决方案。

weixin_30755393的博客 799

PTA甲级刷题1004 Counting Leaves(详细注释版+思路总结)

目录看这里大哥们!PAT甲级刷题笔记(C++)1003 Emergency(最短路径搜索)(1)题目(2)代码和注释(3)归纳与反思功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 PAT甲级刷题笔记(C++) Hello!朋友们俺

HLY:) 的博客 1034

使用PlotNeuralNet绘制深度学习网络图的基本操作

使用PlotNeuralNet绘制深度学习网络图的基本操作

weixin_46877907的博客 2110

耗时3个月,近10W字的刷题笔记,多语言通吃,秒杀 80% Leetcode 题目!

学会了,offer收割机就是你~

Jack-Cui 1万+

电机控制框架选型指南:从TI MotorWare到ST MC SDK,5种架构优缺点对比

本文深入对比了TI MotorWare、ST MC SDK、AUTOSAR、FPGA+ARM及集成方案等五种主流电机控制软件框架的架构特点、实时性、开发效率与硬件兼容性。通过工业伺服和消费电子的实战案例分析,为工程师提供了清晰的选型逻辑与决策清单,旨在帮助规避技术债务,选择最适合项目需求的电机控制框架。

rnn9storyteller的博客 1174

从网格划分到端口接地:一份给ADS新手的Momentum RF仿真避坑实操指南

本文为ADS新手提供Momentum RF仿真的实用指南,涵盖网格划分、端口接地、特殊结构处理等关键设置技巧。通过30-50 cells/λ原则、1/10波长限制等黄金法则,帮助用户平衡仿真精度与效率,避免常见错误,提升电磁仿真结果的准确性。

weixin_33692284的博客 505

[C++]Leetcode超高效刷题顺序及题目详解笔记(持续更新中)

一.引言 博主最近在LeetCode上用C++练习。一路走来踩过一些坑,做了一些总结和笔记,分享给需要的人。 LeetCode网址:https://leetcode.com/ LeetCode中文版:https://leetcode-cn.com/ 二.刷题指南 LeetCode 是一个非常棒的平台,收集了许多公司的面试题目。相对其他平台而言,有着下面的几个优点: 题目全部来自业内大公司的真实面试不用处理输入输出 精力全放在解决具体问题上题目有丰富的讨论 可以参考别人的思路精确了解自己代码在所有提交代码中

cpb____的博客 2万+

【2026年华为秋招(AI)-2月4日-第一题(100分)- 选择题】(题目+思路+Java&C++&Python解析+在线测试)

本文摘要:本文包含20道选择题,涵盖机器学习、线性代数、Transformer架构、概率统计等多个领域。题目涉及正交矩阵性质、Transformer注意力机制、聚类距离度量、ReAct框架、Softmax函数、混淆矩阵计算、Flash-Attention优化、位置编码、期望计算、归一化方法、矩阵迭代法、矩阵秩、大模型架构、神经网络推理、泊松流性质、SVM核函数以及聚类算法等知识点。每道题均提供解析,帮助理解核心概念和解题思路。

m0_73659489的博客 125

关于C/C++语言的初学者在哪刷题,怎么刷题

这篇博客主要是针对初学者关于怎么在网上刷题,以及在哪里刷题。

2401_88433210的博客 6132

GPU 运维实战:H100/H800/B300 换卡与压测

(烧多久、看什么、什么算合格)。文末还给了一个能直接跑的验收判定脚本,三个真实场景的裁决输出都在。

老韩的Linux云计算架构师进阶之路 270

国科大学习资料--数据挖掘(刘莹)--第三章习题及参考答案

国科大学习资料–数据挖掘(刘莹)–第三章习题及参考答案 国科大学习资料–数据挖掘(刘莹)–第三章习题及参考答案 国科大学习资料–数据挖掘(刘莹)–第三章习题及参考答案 第 3 章分类与回归 3.1简述决策树分类的主要步骤。 答:决策树生成的过程如下: (1)对数据源进行数据预处理, 得到训练集和测试集; (2)对训练集进行训练; (3)对初始决策树进行树剪枝; (4)由所得到的决策树提取分类规则; (5)使用测试数据集进行预测,评估决策树模型; 3.2给定决策树,选项有:(1)将决策树转换成规则,然后对结果

无名何许人的博客 3091

C/C++的刷题练习之牛客网,一个友好的网站

一次偶然的机会我登上了牛客网的页面,在我练习c和c++的题时,我发现了这个网站的很多优点,让我很是舒心,例如: 1、干净整洁且具有强提示的代码高亮 2、练习题内容紧凑,很适合系统的复习、巩固 3、调试、运行代码方便 4、模拟大厂的面试题很丰富 因此很推荐大家来这儿坚持日常刷题,哪怕每天只刷一道题也会丰富自己的知识,让自己任何时候都不会出现不认识代码的情况。下面我分享一些我个人在牛客网刷到并解决的题,浅浅的解析,欢迎大家......

叶落秋白的博客 9982

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

刷完 900 多道算法题的首次总结:LeetCode 应该怎么刷?

LeetCode 算法题应该怎么刷?算法题学习路线?怎么组队刷题?有没有算法刷题群? 你是怎么入门 LeetCode 的?刷完 1000 道算法题是什么体验?大家都是怎么刷题的? 新手小白开始刷算法题应该怎么刷,注意什么?刷 LeetCode 总是觉得太难怎么办? 刷算法题有没有书籍推荐?该按照什么顺序刷算法题?LeetCode 怎么看别人的题解?有哪些好的算法题博主推荐?

负雪明烛 13万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C++日常刷题

语言定位C++是一种通用、编译型、静态类型的编程语言,起源于 1980 年代,由 Bjarne Stroustrup 在 C 语言基础上设计,支持面向对象(OOP)、泛型编程(GP)、过程式编程等范式。

2302_80035129的博客 1728

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

c++好用的刷题网址(学习c++的必看系列)

作为学习有很多方向,我按照分类给出。

2201_75356540的博客 1万+

剑指Offer系列刷题笔记汇总

本文转自:个人网站:点击查看 一前言 二总结 链表-8道 二叉树12道 二叉搜索树3道 数组11道 字符串8道 栈3道 递归4道 回溯法2道 其他15道 一、前言 本系列文章为《剑指Offer》刷题笔记。 刷题平台:牛客网 书籍下载:共享资源 刷题刷的比较慢,花费了两个多月,终于将所有题目过了一遍,牛客网一共有66道题,这次刷题主要使用C++,接下来会使用Python...

Jack-Cui 5万+
上一篇: C++刷题笔记:哈希表 map
下一篇: C++刷题笔记:数组
\lambda
博客等级 码龄11年 200粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值