leetcode 834. Sum of Distances in Tree(树中的距离和)

news2024/10/5 13:03:40

在这里插入图片描述
无向连接的树(不一定是二叉树),求每个节点到其他节点的距离和。
返回一个数组,数组的第i个元素就是第i个节点到其他所有节点的距离之和。

思路:

涉及无向图的构造和遍历,树的前序后序遍历,问题拆分

能想到的最笨的办法就是以每个节点为root进行DFS遍历,这样就能求到每个节点到其他所有节点的距离。但是这样要遍历n次。

如何能在O(n)时间内解决?

先看个例子,看节点0到其他所有节点的距离

    0
   / \
  1   2
 / \
3   4

0到1,2的距离都是1,1到3,4的距离是1,
而0到3,4的距离则在1到3,4的距离基础上加1,因为又深了一层,

现在要求的是距离之和,
那么0到3,4的距离之和 = 2(1到3,4的距离之和) + 1* 2(3,4是2个节点,每个节点加深了一层,距离+1)

那么0到所有节点的距离之和呢?
就 = 0到它连接的1,2的距离之和2 + 1到3,4距离和 + 3,4节点数
= 左子树的距离和(1到3,4的距离和+左子树的节点数(1,3,4共3个))
+ 右子树的距离和(2到子树null的距离和 + 右子树的节点数(只有2一个))

所以需要知道以每个节点为root的子树有多少个节点
是一个从下到上遍历的过程,
所以用后序遍历,把结果保存在nodeNums数组。

遍历完之后,我们能得到节点0到其他所有节点的距离之和。

那其他节点怎么办,以1为例来说明。
之前我们求了以1为root的子树的节点数,是3个(1,3,4),

distance_sum[0] = 0到1 + 0到3 + 0到4 + 0到2
而distance_sum[1] = 1到1 + 1到3 + 1到4 + 1到2
可以看到1,3,4都在以1为root的子树中,这3个节点到1的距离比到0的距离少了1,
而这个子树之外的节点0和2,到1的距离比到0的距离多了1,

那么distance_sum[1] = distance_sum[0] - nodeNums[1]*1 + (n - nodeNums[1]) * 1,
这样一层一层往下走,就能得到所有节点的distance_sum[i],
这是一个从上到下遍历的过程,所以用到树的前序遍历

无向图的遍历中需要有flag记录节点是不是已经被访问过,
而现在是树,不会有环的出现,但是因为边是双向的,只需要看当前节点是不是又回到上一节点即可。

class Solution {
    ArrayList<Integer>[] graph;
    int[] dis;
    int[] nodeNums;

    public int[] sumOfDistancesInTree(int n, int[][] edges) {
        dis = new int[n];
        nodeNums = new int[n];
        graph = new ArrayList[n];

        for(int i = 0; i < n; i++) graph[i] = new ArrayList<Integer>();

        //make the graph
        for(int[] edge : edges) {
            graph[edge[0]].add(edge[1]);
            graph[edge[1]].add(edge[0]);
        }

        postOrder(0, -1);  //get node numbers
        preOrder(0, -1, n);   //get distance

        return dis;
    }

    //获取以每个node为root的子树的节点数
    void postOrder(int root, int pre) {
        //left & right for binary tree
        //这里不一定是二叉树,可能是多叉树
        for(Integer node : graph[root]) {
            if(node == pre) continue;
            postOrder(node,root);
            nodeNums[root] += nodeNums[node]; 
            dis[root] += dis[node] + nodeNums[node];
        }
        nodeNums[root] ++; //节点数加上root自己
    }

    void preOrder(int root, int pre, int n) {
        for(Integer node : graph[root]) {
            if(node == pre) continue;
            //dis[root]现在是正确的,而和root连接的点到root的距离要-1,
            //以node为root的子树中的所有节点都需要距离-1,
            //所以dis[node] = dis[root]-1*nodeNums[node]
            //但同时,以node为root的子树之外的其他节点到node的距离要+1
            //这个过程是自上而下的
            dis[node] = dis[root] - nodeNums[node] + n - nodeNums[node];
            preOrder(node, root, n);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/115327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文复现-1:Perturbation CheckLists for Evaluating NLG Evaluation Metrics

以data2text任务为例&#xff0c;探讨generation metric矩阵对于一些句子扰动是否敏感&#xff0c;在多个维度上的敏感性如何&#xff1f; 1数据集 data2text数据集是由3025条samples构成&#xff0c;关键词由“ID”和“reference”构成。 每个子任务由对应的criteria&#…

python基础语法19-calendar模块

一、简介 有了time及datetime模块&#xff0c;再结合日历&#xff08;Calendar&#xff09;模块就可以更好的覆盖到时间处理的各个方面的应用。日历模块主要是用于处理日历及星期相关操作。 calendar模块的内置函数如下: 序号 函数及描述 1 calendar.calendar(yea…

Keras深度学习实战(42)——强化学习基础

Keras深度学习实战&#xff08;42&#xff09;——强化学习基础0. 前言1. 强化学习基础1.1 基本概念1.2 马尔科夫决策过程1.3 目标函数2. 在具有非负奖励的模拟游戏中获取最佳动作2.1 问题设定2.2 模型分析2.3 模型构建与训练3. 在模拟游戏中获取最佳动作3.1 问题定义3.2 模型分…

数据库原理及MySQL应用 | 数据表操作

数据表操作是数据库操作中最基本和最重要的操作。 图5-1是图书销售数据库booksale中存放的图书表books。 ■ 图5-1图书表books 01. 表的结构 表的结构也称为“型”(Type)&#xff0c;用于描述存储于表中的数据的逻辑结构和属性。定义表就是指定义表的结构&#xff0c;使用数据…

Vue CLI系列之生成打包报告

文章の目录一、通过命令行参数的形式生成报告二、通过可视化的UI面板直接查看报告写在最后打包时&#xff0c;为了直观地发现项目中存在的问题&#xff0c;可以在打包时生成报告。生成报告的方式有两种&#xff1a; 一、通过命令行参数的形式生成报告 "scripts": {…

关于对计算机发展史、冯诺依曼体系、CPU基本工作流程以及关于编程语言的简单认识

关于计算机发展史&#xff1a; 关于计算机发展史&#xff0c;大体经历了从一般计算工具到机械计算机到目前的电子计算机的发展历程。 公元前2500年&#xff0c;算盘已经出现&#xff1b; 1694 年&#xff0c;德国博物学家 戈特弗里德莱布尼兹建造了“步进计算器”。 关于步进…

Djiango实现用户管理增删改成功能实战

1.0定义 前后端不分离模式 前后端分离是指前端页面看到的效果都是由后端控制&#xff0c;即后端渲染HTML页面&#xff0c;前端与后端的耦合度比较高 前后端分离模式 后端仅返回前端所需要的数据&#xff0c;不在渲染HTML页面&#xff0c;不在控制前端的效果&#xff0c;至…

八、kubernetes1.25应用升级、回滚

1、概述 用户希望应用程序始终可用&#xff0c;而开发人员则需要每天多次部署它们的新版本。在 Kubernetes 中&#xff0c;这些是通过滚动更新&#xff08;Rolling Updates&#xff09;完成的。 滚动更新 允许通过使用新的实例逐步更新 Pod 实例&#xff0c;零停机进行 Deploym…

Sentinel流控

Sentinel 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 1.sentinel特性 Sentinel 具有以下特征: 丰富的应用场景&#xff1a; Sentinel 承接了…

最优化方法——最小二乘法与梯度下降法

目录 系列文章目录 一、问题 二、实验思路综述 1.实验工具及算法 2.实验数据 3.实验目标 4.实验步骤 三、最小二乘问题引入 1.最小二乘问题样例 2.最小二乘问题解决方案及数学模型化 3.相关线性代数知识导入 3.1 梯度 3.2 矩阵的逆 3.3 QR分解 四、最小二乘法 …

用 ChatGPT 运行 Python

最近&#xff0c;我一直在阅读一些关于ChatGPT的有趣文章。在一篇文章中&#xff0c;有人发明了一种新的语言&#xff0c;并让ChatGPT运行它。在另一篇文章中&#xff0c;有人在ChatGPT中运行一个虚拟机。后者启发我提出了下面这个问题。你能在ChatGPT中运行一个交互式Python会…

【docker常用命令】

一、帮助启动类命令 &#xff08;1&#xff09;启动docker systemctl start docker&#xff08;2&#xff09;停止docker systemctl stop docker&#xff08;3&#xff09;重启docker systemctl restart docker&#xff08;4&#xff09;查看docker状态 systemctl status…

【数据预处理】基于Pandas的数据预处理技术【california_housing加州房价数据集】_后9个任务

文章目录一.需求分析二.需求解决2.1 对第一个特征&#xff08;收入中位数&#xff09;排序后画散点图2.2 对第一个特征&#xff08;收入中位数&#xff09;画分位数图并分析2.3 【选做】对所有特征画分位数图并进行分析2.4 使用线性回归方法拟合第一个特征&#xff08;收入中位…

基于c# asp.net电子病历管理系统的设计与实现

摘 要 网络的广泛应用给生活带来了十分的便利。所以把电子病历管理与现在网络相结合&#xff0c;利用net语言建设电子病历管理系统&#xff0c;实现电子病历管理的信息化。则对于进一步提高医院的发展&#xff0c;丰富电子病历管理经验能起到不少的促进作用。 电子病历管理系统…

AbstractQueueSynchronizer

AbstractQueueSynchronizer AbstractQueueSynchronizer 是基于 FIFO线程等待队列 的一个同步器开发框架。 这篇文章首先介绍同步器概念&#xff0c;然后介绍AQS的结构原理 什么是Synchronizer&#xff08;同步器&#xff09; 并发环境下&#xff0c;Synchronizer用于实现线…

Windows和Mac系统实现本地部署WebPageTest工具

在项目开发或者测试的过程中&#xff0c;由于没有上线&#xff0c;我们在公网上无法访问我们的网站&#xff0c;但同时我们又需要查看浏览器性能&#xff0c;这样我们就需要在本地部署WebPageTest工具以协助进行性能测试 具体实现步骤&#xff1a; Windows系统&#xff1a; …

FFT求多项式乘积

之前在b站上看到了一些介绍FFT的视频 《快速傅里叶变换(FFT)——有史以来最巧妙的算法&#xff1f;》 《这个算法改变了世界》 于是打算写一篇记录一下qwq&#xff08;本博客中的截图基本上来源于第一个视频&#xff09; Fast Fourier Transform 是一种能在O(nlogn)O(nlogn)…

企业营销数字化转型:如何转型、如何选品、如何用好?

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年11月份热门报告盘点2023年&#xff0c;如何科学制定年度规划&#xff1f;《底层逻辑》高清配图清华大学256页PPT元宇宙研究报告.pdf&#xff08;附下载链接&#xff09;…

【LeetCode】1759. 统计同构子字符串的数目

统计同构子字符串的数目 题目描述 给你一个字符串 s &#xff0c;返回 s 中 同构子字符串 的数目。由于答案可能很大&#xff0c;只需返回对 109 7 取余 后的结果。 同构字符串 的定义为&#xff1a;如果一个字符串中的所有字符都相同&#xff0c;那么该字符串就是同构字符串…

自定义报表-FineReport JS实现隐藏Tab页

1. 概述 1.1 问题描述 在实际项目中&#xff0c;使用决策报表的时候&#xff0c;有时会用到在决策报表参数面板获取报表控件的值&#xff0c;那么该如何实现呢&#xff1f; 1.2 实现思路 使用 JS 获取报表主体的控件值&#xff1a; _g().getWidgetByName("area").…