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;
}
在这里插入图片描述
福大大架构师每日一题java当死,golang当立。最新面试题,涉及golang,rust,mysql,redis,云原生,算法,分布式,网络,操作系统。547篇原创内容
公众号
收录于合集 #福大大架构师每日一题
818个
上一篇文心一言 VS 讯飞星火 VS chatgpt (33)-- 算法导论5.2 5题