leetcode 2583.二叉树中的第K大层和

题目

给你一棵二叉树的根节点 root 和一个正整数 k 。

树中的 层和 是指 同一层 上节点值的总和。

返回树中第 k 大的层和(不一定不同)。如果树少于 k 层,则返回 -1 。

注意,如果两个节点与根节点的距离相同,则认为它们在同一层。

示例 1:

输入:root = [5,8,9,2,1,3,7,4,6], k = 2
输出:13
解释:树中每一层的层和分别是:
- Level 1: 5
- Level 2: 8 + 9 = 17
- Level 3: 2 + 1 + 3 + 7 = 13
- Level 4: 4 + 6 = 10
第 2 大的层和等于 13 。

示例 2:

输入:root = [1,2,null,3], k = 1
输出:3
解释:最大的层和是 3 。

提示:

  • 树中的节点数为 n
  • 2 <= n <= 105
  • 1 <= Node.val <= 106
  • 1 <= k <= n

思路

根据题目,要求是把所有的层的和算出来,然后看看第k大的是几,如果有相同排名,导致没有第k个,则返回-1
整个代码都是本学了1年c的菜狗写出来的,如果有可以优化的点,请大佬评论区不吝赐教~

代码

先上总代码

#include <stdlib.h>
int nowLayer = 0;
int maxLayer = 0;void findMaxLayer(struct TreeNode* node, int depth) {if (node == NULL) return;if (depth > maxLayer) maxLayer = depth;findMaxLayer(node->left, depth + 1);findMaxLayer(node->right, depth + 1);
}void searchTree(struct TreeNode* node, long long* sum)
{nowLayer++;sum[nowLayer - 1] += node->val;if(node->left != NULL){searchTree(node->left, sum);}if(node->right != NULL){searchTree(node->right, sum);}nowLayer--;return;
}int compare(const void *a, const void *b) {if (*(long long*)a < *(long long*)b) return 1;if (*(long long*)a > *(long long*)b) return -1;return 0;
}long long kthLargestLevelSum(struct TreeNode* root, int k) {findMaxLayer(root, 1); // 确定树的最大深度long long result = 0;long long *sum = (long long*)malloc(maxLayer * sizeof(long long)); // 动态确定数组长度for (int i = 0; i < maxLayer; ++i) {sum[i] = 0; // 初始化数组}searchTree(root, sum);// 对 sum 数组进行从大到小排序qsort(sum, maxLayer, sizeof(long long), compare);if(k <= maxLayer)result = sum[k - 1];free(sum); // 释放动态分配的内存return (result == 0) ? -1 : result;
}

解析 

变量

int nowLayer = 0;        这个变量是用来存储当前遍历到的是第几层,方便一次遍历填充所有值。

int maxLayer = 0;        这个变量是用来存储最深层数,用来动态分配sum的大小。

刚开始做的时候想的是每个函数都要这俩变量,因此感觉全局好些,不然每个函数会变长。

long long *sum;           这个变量用来储存每一层的层和。

findMaxLayer

  • 时间复杂度:遍历整棵树,时间复杂度为 O(n),其中 n 是树中节点的数量。
  • 空间复杂度:递归调用时,需要额外的栈空间,最大深度为树的高度,空间复杂度为 O(h),其中 h 是树的高度。

这个函数是用来找最深层有多少的,因为题目给的用例不是完全二叉树,空分支的子分支是不会出现在node中的,因此10000个节点的层数假如是链表型,可能会达到5000层,因此动态分配sum数组之前需要遍历一遍。

void findMaxLayer(struct TreeNode* node, int depth) {if (node == NULL) return;if (depth > maxLayer) maxLayer = depth;findMaxLayer(node->left, depth + 1);findMaxLayer(node->right, depth + 1);
}

searchTree 

算法核心,通过DFS,将树遍历一次,每一个非空的节点都将值添加到对应的layer的sum中。

  • 时间复杂度:遍历整棵树,时间复杂度为 O(n),其中 n 是树中节点的数量。
  • 空间复杂度:递归调用时,需要额外的栈空间,最大深度为树的高度,空间复杂度为 O(h),其中 h 是树的高度。另外,sum 数组的空间复杂度为 O(maxLayer),其中 maxLayer 是树的最大深度。
void searchTree(struct TreeNode* node, long long* sum)
{nowLayer++;sum[nowLayer - 1] += node->val;if(node->left != NULL){searchTree(node->left, sum);}if(node->right != NULL){searchTree(node->right, sum);}nowLayer--;return;
}

 compare

这里有个雷点,一开始我写的是

int compare(const void *a, const void *b) {return (*(long long*)a > *(long long*)b);
}

 这样在跑到第43个用例的时候会出错,分析可能是因为有相同的层和,导致某个位置没有被调换。因为qsort使用的是快速排序,在 qsort 函数中,需要提供一个比较函数,该函数用于确定元素之间的顺序。比较函数需要返回一个负值、零或正值,分别表示第一个参数小于、等于或大于第二个参数。这样 qsort 就能根据比较函数的返回值来确定元素的相对顺序。我第一次给的只有1和0的返回值,没有-1,导致出了错。

正确的代码:

int compare(const void *a, const void *b) {if (*(long long*)a < *(long long*)b) return 1;if (*(long long*)a > *(long long*)b) return -1;return 0;
}

kthLargestLevelSum

题目调用的主函数

先获取最深层数,

long long kthLargestLevelSum(struct TreeNode* root, int k) {findMaxLayer(root, 1); // 确定树的最大深度long long result = 0;long long *sum = (long long*)malloc(maxLayer * sizeof(long long)); // 动态确定数组长度for (int i = 0; i < maxLayer; ++i) {sum[i] = 0; // 初始化数组}searchTree(root, sum);// 对 sum 数组进行从大到小排序qsort(sum, maxLayer, sizeof(long long), compare);if(k <= maxLayer)result = sum[k - 1];free(sum); // 释放动态分配的内存return (result == 0) ? -1 : result;
}

结果


另外贴一个官方题解

广度优先搜索 + 排序

思路

(这种题目一般dfs不用动脑,bfs还得分析。。)

先使用广度优先搜索计算出树的每一层的节点值的和,保存在数组 levelSumArray\textit{levelSumArray}levelSumArray 中。然后将数组进行排序,返回第 kkk 大的值。需要考虑数组长度小于 kkk 的边界情况。也可以使用快速选择的算法快速定位第 kkk 大的元素。

代码
#define MAX_NODE_SIZE 100000static long long cmp(const void *a, const void *b) {long long sub = *(long long *)a - *(long long *)b;return sub < 0 ? -1 : 1;
}long long kthLargestLevelSum(struct TreeNode* root, int k) {struct TreeNode **q = (struct TreeNode **)malloc(sizeof(struct TreeNode *) * MAX_NODE_SIZE);long long *levelSumArray = (long long *)malloc(sizeof(long long) * MAX_NODE_SIZE);int head = 0, tail = 0;int pos = 0;q[tail++] = root;while (head != tail) {long long levelSum = 0, size = tail - head;for (int i = 0; i < size; i++) {struct TreeNode *node = q[head];head++;levelSum += node->val;if (node->left) {q[tail++] = node->left;}if (node->right) {q[tail++] = node->right;}}levelSumArray[pos++] = levelSum;}if (pos < k) {return -1;}qsort(levelSumArray, pos, sizeof(long long), cmp);return levelSumArray[pos - k];
}作者:力扣官方题解
链接:https://leetcode.cn/problems/kth-largest-sum-in-a-binary-tree/solutions/2645278/er-cha-shu-zhong-de-di-k-da-ceng-he-by-l-948i/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

复杂度分析

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

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

相关文章

无公网IP情况下如何远程查看本地群晖NAS存储的文件资源

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1. 搭建群晖虚拟机1.1 下载黑群晖文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压黑群晖虚拟机文件1.4 虚拟机初始化1.5 没有搜索到黑群晖的解…

进程1——进程与线程——day09

今天&#xff0c;主要讲一下进程的一些基本概念和一些接口 首先是进程的基本概念&#xff1a; 1.进程: 程序&#xff1a;存放在外存中的一段数据组成的文件 进程&#xff1a;是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡 2.进程相关命令: 1.top 动态…

【Nginx】微信小程序后端开发、一个域名访问多个服务

【Nginx】微信小程序后端开发、一个域名访问多个服务 1. 微信小程序后端开发 对于后端程序员&#xff0c;其实你们的职责就是干老本行&#xff0c;即写接口和服务&#xff0c;让前端能够访问你的接口就行&#xff0c;必要时需要查看微信小程序开发文档去向微信服务器发请求。…

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基…

零基础手把手教你创建微信小程序(二)·创建第一个微信小程序以及了解小程序代码的构成

零基础手把手教你创建微信小程序&#xff08;一&#xff09;微信小程序开发账号的注册以及开发者工具的安装和使用-CSDN博客 目录 ​编辑 1. 创建微信小程序 1.1 基本信息 1.2 在模拟器上查看项目效果 1.3 在真机上预览项目效果 1.4 主界面的5个组成部分 1.4.1 菜单…

NPM私服搭建(verdaccio)

官网地址&#xff1a;https://verdaccio.org/ 概述 Verdaccio 是一个流行的 Node.js 包管理器的代理工具&#xff0c;它允许您在本地或私有网络上轻松地创建和管理 npm 包仓库。通过 Verdaccio&#xff0c;开发团队可以建立自己的 npm 包仓库&#xff0c;以更好地控制和管理其依…

【力扣】Z 字形变换,模拟 + 直接构造

Z 字形变换原题地址 方法一&#xff1a;利用二维矩阵模拟 对于特殊情况&#xff0c;Z 字形变换后只有一行或只有一列&#xff0c;则变换后的字符串和原字符串相同。 对于一般情况&#xff0c;我们可以考虑按照题目要求&#xff0c;把字符串按照 Z 字形存储到二维数组中&…

做抖店想要快速起店怎么办?产品和流量是关键!新手可收藏!

大家好&#xff0c;我是电商小布。 在抖音小店开通完成后&#xff0c;大家考虑的第一件事情&#xff0c;一定是小店如何能够快速出单&#xff0c;成功起店。 店铺出单的重点&#xff0c;其实就在小店的运营上。 那么这么多的环节&#xff0c;关键点在哪呢&#xff1f; 答案…

大学生多媒体课程学习网站thinkphp+vue

开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 运行环境:phpstudy/wamp/xammp等开发背景 &#xff08;一&#xff09; 研究课程的提出 &#xff08;二&#xff09;学习网站的分类与界定…

前端页面之间传输数据 localStorage

效果 发送方 接收方 localStorage 的使用 // 保存数据 localStorage.setItem(key, value); // 获取数据 localStorage.getItem(key);发送方 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>登录<…

【深蓝学院】移动机器人运动规划--第6章 模型预测控制(MPC)与运动规划--笔记

0. Outline 1. Reactive Control&#xff08;反应式控制&#xff09; 控制学中的 “Reactive Control” 通常指的是一种控制策略&#xff0c;它依赖于系统对特定事件或变化的即时反应&#xff0c;而不是按照预定的计划或策略行动。这种控制往往是基于当前的传感器输入来做出决…

c编译器学习07:minilisp编译器改造(debug模式支持调试)

问题 原版的minilisp编译器不支持argv输入测试&#xff0c;不方便单步调试。 代码改造目标是既不改变原有程序的各种功能&#xff0c; 又能支持个人习惯的vs单步debug模式。 CMakeLists.txt变更 定义DEBUG宏 解决单步调试源码定位偏差问题 cmake_minimum_required(VERSION …

【Android安全】Windows 环境下载 Android 源码

准备环境 安装 git 安装 Python 硬盘剩余容量最好大于 100G 打开 Git Bash&#xff0c;用 git 克隆源代码仓库 git clone https://android.googlesource.com/platform/manifest.git //没有梯子使用清华源 git clone https://aosp.tuna.tsinghua.edu.cn/platform/manifest.git…

RabbitMQ 部署方式选择

部署模式 RabbitMQ支持多种部署模式&#xff0c;可以根据应用的需求和规模选择适合的模式。以下是一些常见的RabbitMQ部署模式&#xff1a; 单节点模式&#xff1a; 最简单的部署方式&#xff0c;所有的RabbitMQ组件&#xff08;消息存储、交换机、队列等&#xff09;都运行在…

TensorRT及CUDA自学笔记003 NVCC及其命令行参数

TensorRT及CUDA自学笔记003 NVCC及其命令行参数 各位大佬&#xff0c;这是我的自学笔记&#xff0c;如有错误请指正&#xff0c;也欢迎在评论区学习交流&#xff0c;谢谢&#xff01; NVCC是一种编译器&#xff0c;基于一些命令行参数可以将使用PTX或C语言编写的代码编译成可…

新手如何自己建网站的详细步骤?-网站建设

新手如何自己建网站的详细步骤&#xff1f;-网站建设 我们选择了白嫖雨云的二级域名 浏览器输入https://www.rainyun.com/z22_ 创建账号然后选择一个你喜欢的子域名我建议后缀选择ates.top的 选择自定义地址&#xff0c;类型选择cname 现在要选择记录值了&#xff0c;有a&…

linux内核原理--页高速缓存,回写,页框回收

1.页高速缓存 我们主要分析下磁盘文件的页高速缓存 struct address_space {struct inode *host; struct radix_tree_root page_tree; spinlock_t tree_lock;unsigned int i_mmap_writable;struct prio_tree_root i_mmap; struct list_head i_mmap_nonlinear;spinlock_t i_…

2023最新简绘AI开源版支持MJ绘画,AI问答

应用介绍 本文来自&#xff1a;2023最新简绘AI开源版支持MJ绘画&#xff0c;AI问答 - 源码1688 简介&#xff1a; 简绘AI开源版&#xff0c;从闲鱼上买的&#xff0c;搭建教程如下 测试环境&#xff1a;NginxPHP7.4MySQL5.6 图片&#xff1a;

com.alibaba.nacos.api.exception.NacosException: Request nacos server failed

问题描述 安装nacos2.0以上版本&#xff0c;启动报错:com.alibaba.nacos.api.exception.NacosException: Request nacos server failed com.alibaba.nacos.api.exception.NacosException: Request nacos server failed: at com.alibaba.nacos.client.naming.remote.gprc.Nami…

2024022402-数据库恢复技术

数据库恢复技术 什么是事务 事务(Transaction)是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做&#xff0c;要么全不做&#xff0c;是一个不可分割的工作单位 事务和程序是两个概念 在关系数据库中&#xff0c;一个事务可以是一条SQL语句&#xff0c;一组SQL语…