【回溯算法】N叉树相关技巧
我个人认为,想玩得转回溯算法,N叉树的遍历是必备的。于是我就来把这块石头搬开。
前言
二叉树是一棵以根节点开始,每个节点含有不超过 2 个子节点的树。让我们将这个定义扩展到 N 叉树 。 一棵以根节点开始,每个节点不超过 N 个子节点的树,称为 N叉树 。 各位自行脑补。
N叉树的遍历
回顾 - 二叉树的遍历 前序遍历 - 首先访问根节点,然后遍历左子树,最后遍历右子树; 中序遍历 - 首先遍历左子树,然后访问根节点,最后遍历右子树; 后序遍历 - 首先遍历左子树,然后遍历右子树,最后访问根节点; 层序遍历 - 按照从左到右的顺序,逐层遍历各个节点。
N 叉树的中序遍历没有标准定义,中序遍历只有在二叉树中有明确的定义。 我们跳过 N 叉树中序遍历的部分。
后面的栗子都用这个图了
数据结构
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
N叉树的前序遍历
给定一个 N 叉树,返回其节点值的前序遍历。
代码实现
class Solution {
public:
void preorderDFS(Node* root, int index, vector<int>& ret) {
if (root == NULL)
return;
ret.push_back(root->val);
int sz = (root->children).size();
while (index < sz) {
preorderDFS(root->children[index], 0, ret);
index += 1;
}
}
vector<int> preorder(Node* root) {
vector<int> ret;
preorderDFS(root, 0, ret);
return ret;
}
};
后序遍历
给定一个 N 叉树,返回其节点值的后序遍历。
代码实现
class Solution {
public:
void postorderDFS(Node* root, int index, vector<int>& ret) {
if (root == NULL)
return;
int sz = (root->children).size();
while (index < sz) {
postorderDFS(root->children[index], 0, ret);
index += 1;
}
ret.push_back(root->val);
}
vector<int> postorder(Node* root) {
vector<int> ret;
postorderDFS(root, 0, ret);
return ret;
}
};
层序遍历
给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
class Solution {
public:
vector<vector<int>> result;
void dfs(Node* root, int dep){
if(!root) return;
if(dep == result.size()) result.emplace_back();
result[dep].push_back(root->val);
auto children = root->children;
for(auto ele:children){
dfs(ele, dep+1);
}
}
vector<vector<int>> levelOrder(Node* root) {
dfs(root, 0);
return result;
}
};
N叉树的经典递归解法
- "自顶向下"的解决方案 "自顶向下"意味着在每个递归层次上,我们首先访问节点以获得一些值,然后在调用递归函数时,将这些值传给其子节点。
一个典型的 “自顶向下” 函数 top_down(root, params) 的工作原理如下:
- 对于 null 节点返回一个特定值
- 如果有需要,对当前答案 answer 进行更新 // answer <-- params
- for each child node root.children[k]:
- ans[k] = top_down(root.children[k], new_params[k]) // new_params <-- root.val, params
- 如果有需要,返回答案 answer // answer <-- all ans[k]
- "自底向上"的解决方案 “自底向上” 意味着在每个递归层次上,我们首先为每个子节点递归地调用函数,然后根据返回值和根节点本身的值给出相应结果。
一个典型的 “自底向上” 函数 bottom_up(root) 的工作原理如下:
1.对于 null 节点返回一个特定值 2.for each child node root.children[k]: 3. ans[k] = bottom_up(root.children[k]) // 为每个子节点递归地调用函数 4. 返回答案 answer // answer <- root.val, all ans[k]
作者:力扣 (LeetCode) 链接:https://leetcode-cn.com/leetbook/read/n-ary-tree/x0ucsg/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
N叉树的最大深度
给定一个 N 叉树,找到其最大深度。 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
class Solution {
public:
int maxDepth(Node* root) {
if (root == NULL)return 0;
int height = 0;
for (int i = 0; i < root->children.size(); i++) {
height = max(height, maxDepth(root->children[i]));
}
return height + 1;
}
};
- 使用虚拟环境,搭建python3+scrapy
- Matplotlib基础全攻略
- Python 小爬虫 - 爬取今日头条街拍美女图
- python3使用zookeeper和私钥解密及编码转化配置信息
- Python中os.path.dirname(__file__)的用法
- TensorFlow从0到1 - 18 - TensorFlow 1.3.0安装手记
- Python + Splinter 实现浏览器自动化操作入门指南
- 动态地理信息可视化——leaflet在线地图简介
- python中的递归函数
- 对抗思想与强化学习的碰撞-SeqGAN模型原理和代码解析
- 玩转数据地图系列之——地图上的迷你条形图
- 树上倍增求LCA及例题
- 深度强化学习-DDPG算法原理和实现
- 你绝对想不到,数据地图还能这么玩~
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 浅谈Android 的线程和线程池的使用
- 点餐系统的部署,Java点餐系统部署到腾讯云Linux服务器
- 详解Android 中AsyncTask 的使用
- 解决Android应用冷启动时出现的白屏问题的方法
- Java点餐系统+扫码点餐小程序部署文档(2020版)
- Android开发实现各种图形绘制功能示例
- Android webview手动校验https证书(by 星空武哥)
- AndroidStudio Gradle第三依赖统一管理的实现方法
- 小程序上传多张图片到springboot后台,返回可供访问的图片链接
- AndroidStudio Gradle基于友盟的多渠道打包方法
- Android开发之全屏与非全屏的切换设置方法小结
- Android使用GridView实现日历的方法
- Android控件AppWidgetProvider使用方法详解
- R语言使用链梯法Chain Ladder和泊松定律模拟和预测未来赔款数据
- Android ViewPager实现左右滑动的实例