首页 > 编程语言 >2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分别位于 (row + 1, col -

2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分别位于 (row + 1, col -

时间:2023-06-06 21:03:22浏览次数:56  
标签:结点 06 TreeNode int 二叉树 collects root col row

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表示节点值和LeftRight分别表示左右节点。

2.定义结构体Info表示节点信息,包含属性rowcolval分别表示节点所在的行、列和值。

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;
}

在这里插入图片描述

标签:结点,06,TreeNode,int,二叉树,collects,root,col,row
From: https://www.cnblogs.com/moonfdd/p/17461682.html

相关文章

  • 202306062001-《远程Linux服务器——安装tomcat8、jdk1.8、mysql5——mysql 用sql建表
    因createtable...提示格式错误,什么NAME啊...,必查了一下,要设置,好多条语句(5条左右),是设置格式的。 但设置完了,说重启mysql,就失效,要重新设置(5条sql重新执行一遍!) 永久有效的解决办法是:修改“my.cnf”,我的修改如下:[client]default-character-set=utf8[mysql]default-......
  • 欧奈儿行业 RPS 排名,一图览全貌 2023-06-06
    自动复盘2023-06-06k线图是最好的老师,点击详情图可以看到行业20日RPS的排名,最底下子图是行业rps走势线跟踪板块总结:成交额超过100亿排名靠前,macd柱由绿转红公众hao:醉卧梦星河欧奈尔行业RPS排名天天更新追踪主力行业趋势更容......
  • 2023-06-06 hexo 去除博客中的“嗯..! 目前共计”字样
    注意:我使用的是next主题。找到路径:你的博客\themes\hexo-theme-next\layout,修改archive.swig文件:修改前:<spanclass="archive-page-counter">{%setcheers%}{%setposts_length=site.posts.length%}{%ifposts_length>210%}{%s......
  • Google Guice 入门教程06 – Web 和 Servlet
    3Web和Servlet3.1快速开始我们从一个例子开始GuiceWeb的开发。首先准备我们的环境,由于是web开发,因此我们需要guice-servlet的jar包。log4j不是必须的,只是为了方便日志记录而已(Guice内部是使用jdk内部的logging包来完成日志记录的)。必可避免的要在web.xml中都一些手脚,这里先配......
  • 【2023-06-04】连岳摘抄
    23:59一个钉子挤掉另一个钉子,习惯要由习惯来取代。                                                 ——伊拉斯谟你老公没错,大孝子。你婆婆也没错,人老了,必然在身心......
  • 算法学习day44动态规划part06-518、377
    packageLeetCode.DPpart06;/***518.零钱兑换II*给你一个整数数组coins表示不同面额的硬币,另给一个整数amount表示总金额。*请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回0。*假设每一种面额的硬币有无限个。*题目数......
  • 2023.06.05锻炼这件事
    周五晚上左搞右搞,晚上搞到半夜,周六起不来,下午也近乎荒废周天正常休息,就是眼睛不太行,看了漫长的季节,我的内耗减少了,晚上看了夕阳,眼睛得到了很好的休息,生活不易,保护眼睛,好好休息周一早上去锻炼了,感觉一天都有精神了,加油,加油,加油!......
  • 代码随想录Day17|二叉树(五)
     今日任务513.找树左下角的值112. 路径总和  113.路径总和ii106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树100.相同的树572.另一个树的子树 513.找树左下角的值层序遍历/***Definitionforabinarytreenode.*publiccl......
  • 2023-06-05:Redis官方为什么不提供 Windows版本?
    2023-06-05:Redis官方为什么不提供Windows版本?答案2023-06-05:Redis官方没有提供Windows版本有几个原因。1.Redis的开发团队规模较小,由三四名核心开发者组成。他们更加熟悉和习惯Unix-like系统,在这些系统上进行开发和测试可以更高效地进行。然而,提供Windows版本会消耗较多资源,可......
  • 2023-06-05:Redis官方为什么不提供 Windows版本?
    2023-06-05:Redis官方为什么不提供Windows版本?答案2023-06-05:Redis官方没有提供Windows版本有几个原因。1.Redis的开发团队规模较小,由三四名核心开发者组成。他们更加熟悉和习惯Unix-like系统,在这些系统上进行开发和测试可以更高效地进行。然而,提供Windows版本会消耗较多资源,可能会......