2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分别位于 (row + 1, col -
2023/6/7 1:22:28
本文主要是介绍2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分别位于 (row + 1, col -,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。
对位于 (row, col) 的每个结点而言,
其左右子结点分别位于 (row + 1, col - 1) 和 (row + 1, col + 1)
树的根结点位于 (0, 0) 。
二叉树的 垂序遍历 从最左边的列开始直到最右边的列结束,按列索引每一列上的所有结点,
形成一个按出现位置从上到下排序的有序列表。如果同行同列上有多个结点,
则按结点的值从小到大进行排序。
返回二叉树的 垂序遍历 序列。
输入:root = [3,9,20,null,null,15,7]。
输出:[[9],[3,15],[20],[7]]。
答案2023-06-06:
大体过程如下:
1 定义结构体TreeNode
表示二叉树节点,包含属性Val
表示节点值和Left
和Right
分别表示左右节点。
2.定义结构体Info
表示节点信息,包含属性row
、col
和val
分别表示节点所在的行、列和值。
3.定义函数NewInfo()
创建节点信息。
4.定义切片类型ByColThenRowThenVal
并实现其三个方法Len()
、Less()
和Swap()
使之按列、行和节点值排序。
5.定义函数verticalTraversal()
实现二叉树的垂序遍历。
6.在verticalTraversal()
中,创建切片collects
存储各节点信息,并将根节点的信息存入其中。
7.调用函数dfs()
遍历整个二叉树,添加各节点的信息到collects
中。
8.对collects
按列、行和节点值排序。
9.遍历collects
,将同列的所有节点值存入一个新的子切片,将子切片添加到答案ans
中。
10.返回答案ans
。
时间复杂度是O(nlogn),其中n是节点数。n个节点需要遍历一次,排序时间复杂度是O(nlogn)。所以总时间复杂度是O(nlogn)。
空间复杂度是O(n),其中n是节点数。需要使用切片collects来存储节点的信息,collects的长度最大是n,所以空间复杂度是O(n)。
golang完整代码如下:
package main import ( "fmt" "sort" ) type TreeNode struct { Val int Left *TreeNode Right *TreeNode } type Info struct { row int col int val int } func NewInfo(r, c, v int) Info { return Info{row: r, col: c, val: v} } type ByColThenRowThenVal []Info func (bc ByColThenRowThenVal) Len() int { return len(bc) } func (bc ByColThenRowThenVal) Less(i int, j int) bool { if bc[i].col != bc[j].col { return bc[i].col < bc[j].col } if bc[i].row != bc[j].row { return bc[i].row < bc[j].row } return bc[i].val < bc[j].val } func (bc ByColThenRowThenVal) Swap(i int, j int) { bc[i], bc[j] = bc[j], bc[i] } func verticalTraversal(root *TreeNode) [][]int { collects := make([]Info, 0, 1000) rootInfo := NewInfo(0, 0, root.Val) collects = append(collects, rootInfo) dfs(root, rootInfo, &collects) sort.Sort(ByColThenRowThenVal(collects)) ans := make([][]int, 0, 1000) for i := 0; i < len(collects); i++ { if i == 0 || collects[i-1].col != collects[i].col { ans = append(ans, []int{}) } ans[len(ans)-1] = append(ans[len(ans)-1], collects[i].val) } return ans } func dfs(root *TreeNode, rootInfo Info, collects *[]Info) { if root.Left != nil { leftInfo := NewInfo(rootInfo.row+1, rootInfo.col-1, root.Left.Val) *collects = append(*collects, leftInfo) dfs(root.Left, leftInfo, collects) } if root.Right != nil { rightInfo := NewInfo(rootInfo.row+1, rootInfo.col+1, root.Right.Val) *collects = append(*collects, rightInfo) dfs(root.Right, rightInfo, collects) } } func main() { leaf7 := &TreeNode{7, nil, nil} leaf15 := &TreeNode{15, nil, nil} leaf20 := &TreeNode{20, leaf15, leaf7} leaf9 := &TreeNode{9, nil, nil} root := &TreeNode{3, leaf9, leaf20} result := verticalTraversal(root) fmt.Println(result) }
c++完整代码如下:
#include <iostream> #include <vector> #include <algorithm> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {} }; struct Info { int row; int col; int val; Info(int r, int c, int v) { row = r; col = c; val = v; } }; struct InfoComparator { bool operator() (const Info& o1, const Info& o2) { if (o1.col != o2.col) { return o1.col < o2.col; } if (o1.row != o2.row) { return o1.row < o2.row; } return o1.val < o2.val; } }; void dfs(TreeNode* root, Info rootInfo, vector<Info>& collects) { if (root->left != nullptr) { Info leftInfo(rootInfo.row + 1, rootInfo.col - 1, root->left->val); collects.push_back(leftInfo); dfs(root->left, leftInfo, collects); } if (root->right != nullptr) { Info rightInfo(rootInfo.row + 1, rootInfo.col + 1, root->right->val); collects.push_back(rightInfo); dfs(root->right, rightInfo, collects); } } vector<vector<int>> verticalTraversal(TreeNode* root) { vector<Info> collects; Info rootInfo(0, 0, root->val); collects.push_back(rootInfo); dfs(root, rootInfo, collects); sort(collects.begin(), collects.end(), InfoComparator()); vector<vector<int>> ans; for (int i = 0; i < collects.size(); i++) { if (i == 0 || collects[i - 1].col != collects[i].col) { ans.push_back(vector<int>()); } ans.back().push_back(collects[i].val); } return ans; } int main() { TreeNode* leaf7 = new TreeNode(7); TreeNode* leaf15 = new TreeNode(15); TreeNode* leaf20 = new TreeNode(20, leaf15, leaf7); TreeNode* leaf9 = new TreeNode(9); TreeNode* root = new TreeNode(3, leaf9, leaf20); vector<vector<int>> result = verticalTraversal(root); for (int i = 0; i < result.size(); i++) { for (int j = 0; j < result[i].size(); j++) { cout << result[i][j] << " "; } cout << endl; } return 0; }
这篇关于2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分别位于 (row + 1, col -的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-09CMS内容管理系统是什么?如何选择适合你的平台?
- 2025-01-08CCPM如何缩短项目周期并降低风险?
- 2025-01-08Omnivore 替代品 Readeck 安装与使用教程
- 2025-01-07Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
- 2025-01-06PingCAP 连续两年入选 Gartner 云数据库管理系统魔力象限“荣誉提及”
- 2025-01-05Easysearch 可搜索快照功能,看这篇就够了
- 2025-01-04BOT+EPC模式在基础设施项目中的应用与优势
- 2025-01-03用LangChain构建会检索和搜索的智能聊天机器人指南
- 2025-01-03图像文字理解,OCR、大模型还是多模态模型?PalliGema2在QLoRA技术上的微调与应用
- 2025-01-03混合搜索:用LanceDB实现语义和关键词结合的搜索技术(应用于实际项目)