【LeetCode周赛】LeetCode第370场周赛

目录

  • 找到冠军 I
  • 找到冠军 II
  • 在树上执行操作以后得到的最大分数
  • 平衡子序列的最大和

找到冠军 I

一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。
给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 <= i, j <= n - 1 且 i != j 的所有 i, j :如果 grid[i][j] == 1,那么 i 队比 j 队 强 ;否则,j 队比 i 队 强 。
在这场比赛中,如果不存在某支强于 a 队的队伍,则认为 a 队将会是 冠军 。
返回这场比赛中将会成为冠军的队伍。

示例 1:

输入:grid = [[0,1],[0,0]]
输出:0
解释:比赛中有两支队伍。 grid[0][1] == 1 表示 0 队比 1队强。所以 0 队是冠军。

示例 2:

输入:grid = [[0,0,1],[1,0,1],[0,0,0]]
输出:1
解释:比赛中有三支队伍。 grid[1][0] == 1表示 1 队比 0 队强。 grid[1][2] == 1 表示 1 队比 2 队强。 所以 1 队是冠军。

提示:
n = = g r i d . l e n g t h n == grid.length n==grid.length
n = = g r i d [ i ] . l e n g t h n == grid[i].length n==grid[i].length
2 < = n < = 100 2 <= n <= 100 2<=n<=100
g r i d [ i ] [ j ] grid[i][j] grid[i][j] 的值为 0 0 0 1 1 1
对于满足 i ! = j i != j i!=j 的所有 i , j i, j i,j g r i d [ i ] [ j ] ! = g r i d [ j ] [ i ] grid[i][j] != grid[j][i] grid[i][j]!=grid[j][i] 均成立
生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

分析:
这个题目,因为如果 g r i d [ i ] [ j ] = = 1 grid[i][j] == 1 grid[i][j]==1,那么 i i i队比 j j j 队强,那么我们需要找到冠军队伍,则 冠军队伍 i i i g r i d [ i ] [ j ] = = 1 grid[i][j] == 1 grid[i][j]==1对所有的 j ( j ! = i ) j(j!=i) j(j!=i)恒成立,所以只要找到一个满足该条件的队伍,即是答案。
代码:

class Solution {
public:int findChampion(vector<vector<int>>& grid) {int n = grid.size();for(int i = 0; i < n ; i++){bool flag = 1;for(int j = 0; j < n; j++){if(i != j){if(!grid[i][j])flag=0;}}if(flag)return i;}return 0;}
};

找到冠军 II

一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。每支队伍也是 有向无环图(DAG) 上的一个节点。
给你一个整数 n 和一个下标从 0 开始、长度为 m 的二维整数数组 edges 表示这个有向无环图,其中 edges[i] = [ui, vi] 表示图中存在一条从 ui 队到 vi 队的有向边。
从 a 队到 b 队的有向边意味着 a 队比 b 队 强 ,也就是 b 队比 a 队 弱 。
在这场比赛中,如果不存在某支强于 a 队的队伍,则认为 a 队将会是 冠军 。
如果这场比赛存在 唯一 一个冠军,则返回将会成为冠军的队伍。否则,返回 -1 。
注意
环 是形如 a1, a2, …, an, an+1 的一个序列,且满足:节点 a1 与节点 an+1 是同一个节点;节点 a1, a2, …, an 互不相同;对于范围 [1, n] 中的每个 i ,均存在一条从节点 ai 到节点 ai+1 的有向边。
有向无环图 是不存在任何环的有向图。

示例 1:
在这里插入图片描述

输入:n = 3, edges = [[0,1],[1,2]]
输出:0
解释:1 队比 0 队弱。2 队比 1 队弱。所以冠军是 0 队。

示例 2:
在这里插入图片描述

输入:n = 4, edges = [[0,2],[1,3],[1,2]]
输出:-1
解释:2 队比 0 队和 1 队弱。3 队比 1队弱。但是 1 队和 0 队之间不存在强弱对比。所以答案是 -1 。

提示:
1 < = n < = 100 1 <= n <= 100 1<=n<=100
m = = e d g e s . l e n g t h m == edges.length m==edges.length
0 < = m < = n ∗ ( n − 1 ) / 2 0 <= m <= n * (n - 1) / 2 0<=m<=n(n1)/2
e d g e s [ i ] . l e n g t h = = 2 edges[i].length == 2 edges[i].length==2
0 < = e d g e [ i ] [ j ] < = n − 1 0 <= edge[i][j] <= n - 1 0<=edge[i][j]<=n1
e d g e s [ i ] [ 0 ] ! = e d g e s [ i ] [ 1 ] edges[i][0] != edges[i][1] edges[i][0]!=edges[i][1]
生成的输入满足:如果 a 队比 b 队强,就不存在 b 队比 a 队强
生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

分析:
相比于第一题是利用矩阵给出强弱关系,本题是直接给出图中每一条边,来代表强弱关系。其实和第一题思考方式一致,如果存在答案,那么最强的队伍,即冠军队伍是不可能存在一条边指向它的,即入度为0。那么我们只需要判断入度为0的点是不是有且仅有一个即可。
代码:

class Solution {
public:int findChampion(int n, vector<vector<int>>& edges) {//有答案的话,入度为0的点有且只能有一个,否则会存在无法比较强弱的情况int m = edges.size();vector<int>in(n + 1, 0);for(int i = 0; i < m; i++){in[edges[i][1]]++;}int cnt = 0, ans = -1;for(int i = 0; i < n; i++){if(!in[i]){cnt++;ans = i;}}if(cnt == 1)return ans;return -1;}
};

在树上执行操作以后得到的最大分数

有一棵 n 个节点的无向树,节点编号为 0 到 n - 1 ,根节点编号为 0 。给你一个长度为 n - 1 的二维整数数组 edges 表示这棵树,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 有一条边。
同时给你一个长度为 n 下标从 0 开始的整数数组 values ,其中 values[i] 表示第 i 个节点的值。
一开始你的分数为 0 ,每次操作中,你将执行:
选择节点 i 。
将 values[i] 加入你的分数。
将 values[i] 变为 0 。
如果从根节点出发,到任意叶子节点经过的路径上的节点值之和都不等于 0 ,那么我们称这棵树是 健康的 。
你可以对这棵树执行任意次操作,但要求执行完所有操作以后树是 健康的 ,请你返回你可以获得的 最大分数 。

示例 1:
在这里插入图片描述

输入:edges = [[0,1],[0,2],[0,3],[2,4],[4,5]], values = [5,2,5,2,1,1]
输出:11
解释:我们可以选择节点 1 ,2 ,3 ,4 和 5 。根节点的值是非 0 的。所以从根出发到任意叶子节点路径上节点值之和都不为0 。所以树是健康的。你的得分之和为 values[1] + values[2] + values[3] + values[4] +values[5] = 11 。 11 是你对树执行任意次操作以后可以获得的最大得分之和。

示例 2:
在这里插入图片描述

输入:edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]], values =
[20,10,9,7,4,3,5]
输出:40
解释:我们选择节点 0 ,2 ,3 和 4 。

  • 从 0 到 4 的节点值之和为 10 。
  • 从 0 到 3 的节点值之和为 10 。
  • 从 0 到 5 的节点值之和为 3 。
  • 从 0 到 6 的节点值之和为 5 。
    所以树是健康的。你的得分之和为 values[0] + values[2] + values[3] + values[4] = 40 。 40 是你对树执行任意次操作以后可以获得的最大得分之和。

提示:
2 < = n < = 2 ∗ 1 0 4 2 <= n <= 2 * 10^4 2<=n<=2104
e d g e s . l e n g t h = = n − 1 edges.length == n - 1 edges.length==n1
e d g e s [ i ] . l e n g t h = = 2 edges[i].length == 2 edges[i].length==2
0 < = a i , b i < n 0 <= ai, bi < n 0<=ai,bi<n
v a l u e s . l e n g t h = = n values.length == n values.length==n
1 < = v a l u e s [ i ] < = 1 0 9 1 <= values[i] <= 10^9 1<=values[i]<=109
输入保证 edges 构成一棵合法的树。

分析:
一个树形DP的题目,因为取出一个点的 v a l u e value value之后,该点的 v a l u e value value会变成0,又有条件,从根节点出发,到任意叶子节点经过的路径上的节点值之和都不等于 0 ,那么我们称这棵树是健康的。为了达到健康的目的,我们需要判断当前结点选or不选所带来的影响。

  • 如果不选当前结点,那么该结点u的下面的所有子结点的value值都可以选择,即以该节点为根节点的树的value和。因为不管怎样走,经过该结点时结点值肯定不为0了,此时 a n s 1 = s u m [ u ] ans1 = sum[u] ans1=sum[u]
  • 如果选择该结点v,那么下面的所有路径中,每条路径都至少要选择一个点, a n s 2 = v a l u e s [ u ] + d f s _ a n s ( v , u ) ans2 = values[u] + dfs\_ans(v , u) ans2=values[u]+dfs_ans(v,u)(v为所有的u能到达的点)。
    怎样保证下面的结点至少有一个点被选呢, a n s 1 ans1 ans1的值其实就是选了点的情况,那么如果走到了叶子节点,那么叶子结点的值肯定不选。因为叶子节点的前驱节点 p r e pre pre,如果选择了 p r e pre pre(走到了 p r e pre pre,说明前面的结点肯定都选择了),则其叶子节点肯定不能选。如果没有选择 p r e pre pre,那么上一层递归中的 a n s 1 = s u m [ p r e ] ans1 = sum[pre] ans1=sum[pre]包含了叶子结点的值。所以不管怎样都不选择叶子节点,也满足了树要健康的要求。
    sum数组记录了每一个结点的子树中的value的和(不包括当前结点),也可以用一个dfs进行计算。

代码:

class Solution {
public:long long maximumScoreAfterOperations(vector<vector<int>>& edges, vector<int>& values) {//先计算出每一个子树的价值和int n = values.size();vector<int>e[n + 1];vector<long long>sum(n + 1, 0);for(int i = 0; i < n - 1; i++){e[edges[i][0]].push_back(edges[i][1]);e[edges[i][1]].push_back(edges[i][0]);}function<long long(int, int)> dfs_sum = [&](int u, int pre) -> long long{long long cnt = 0;for(auto v: e[u]){if(v == pre)continue;cnt += dfs_sum(v, u) + values[v];}return sum[u] = cnt;};dfs_sum(0, -1);function<long long(int, int)> dfs_ans = [&](int u, int pre) -> long long{//不选当前结点long long ans1 = sum[u];if(ans1 == 0)return 0; //叶子结点//选当前结点long long ans2 = values[u];for(auto v: e[u]){if(v == pre)continue;ans2 += dfs_ans(v, u);}return max(ans1, ans2);};return dfs_ans(0, -1);}
};

平衡子序列的最大和

给你一个下标从 0 开始的整数数组 nums 。
nums 一个长度为 k 的 子序列 指的是选出 k 个 下标 i_0 < i_1 < … < i_{k-1} ,如果这个子序列满足以下条件,我们说它是 平衡的 :
对于范围 [1, k - 1] 内的所有 j , n u m s [ i j ] − n u m s [ i j − 1 ] > = i j − i j − 1 nums[i_j] - nums[i_{j-1}] >= i_j - i_{j-1} nums[ij]nums[ij1]>=ijij1都成立。
nums 长度为 1 的 子序列 是平衡的。
请你返回一个整数,表示 nums 平衡 子序列里面的 最大元素和 。
一个数组的 子序列 指的是从原数组中删除一些元素(也可能一个元素也不删除)后,剩余元素保持相对顺序得到的 非空 新数组。

示例 1:

输入:nums = [3,3,5,6]
输出:14
解释:这个例子中,选择子序列 [3,5,6] ,下标为 0 ,2 和 3 的元素被选中。nums[2] - nums[0] >= 2 - 0 。 nums[3] - nums[2] >= 3 - 2 。所以,这是一个平衡子序列,且它的和是所有平衡子序列里最大的。 包含下标 1 ,2 和 3 的子序列也是一个平衡的子序列。 最大平衡子序列和为14 。

示例 2:

输入:nums = [5,-1,-3,8]
输出:13
解释:这个例子中,选择子序列 [5,8] ,下标为 0 和 3 的元素被选中。nums[3] - nums[0] >= 3 - 0 。 所以,这是一个平衡子序列,且它的和是所有平衡子序列里最大的。 最大平衡子序列和为13 。

示例 3:

输入:nums = [-2,-1]
输出:-1
解释:这个例子中,选择子序列 [-1] 。 这是一个平衡子序列,而且它的和是 nums所有平衡子序列里最大的。

提示:
1 < = n u m s . l e n g t h < = 1 0 5 1 <= nums.length <= 10^5 1<=nums.length<=105
− 1 0 9 < = n u m s [ i ] < = 1 0 9 -10^9 <= nums[i] <= 10^9 109<=nums[i]<=109

分析:
对于每一个长度为k的子序列,需要满足对于范围 [ 1 , k − 1 ] [1, k - 1] [1,k1]内的所有 j j j n u m s [ i j ] − n u m s [ i j − 1 ] > = i j − i j − 1 nums[i_j] - nums[i_{j-1}] >= i_j - i_{j-1} nums[ij]nums[ij1]>=ijij1都成立。我们可以转换一下变成 n u m s [ i j ] − i j > = n u m s [ i j − 1 ] − i j − 1 ( i > j ) nums[i_j] - i_j >=nums[i_{j-1}] - i_{j-1} \ (i > j) nums[ij]ij>=nums[ij1]ij1 (i>j)。所以我们可以令序列 b [ i ] = n u m s [ i ] − i b[i] = nums[i] - i b[i]=nums[i]i,则我们要得到的这个子序列 b [ i ] b[i] b[i]是一个非严格递增子序列。对于所有满足条件的序列 b b b,要得到一个 s u m ( n u m s ) sum(nums) sum(nums)最大的子序列。
我们定义 f [ i ] f[i] f[i]表示子序列的最后一个数的下标为i时,对应的元素和最大的值,那么最后的答案就是 m a x ( f ) max(f) max(f)
状态转移方程为 f [ i ] = m a x j m a x ( f [ j ] , 0 ) + n u m s [ i ] f[i] = max_{j}\ max(f[j],0) + nums[i] f[i]=maxj max(f[j],0)+nums[i]
j < i j < i j<i,且 b [ j ] < b [ i ] b[j] < b[i] b[j]<b[i],如果 f [ j ] < 0 f[j] < 0 f[j]<0,则不取 f [ j ] f[j] f[j],只取当前的数,前面的数都不选。
那么如何维护一个前缀的最大值呢,可以使用树状数组来实现,下标 x = b [ i ] x = b[i] x=b[i],所以可以先将b[i]排序之后进行离散化,再使用树状数组。

代码:

class Solution {
public:int bitset(int x){return x & -x;}long long maxBalancedSubsequenceSum(vector<int>& nums) {int n = nums.size();auto b = nums;// 离散化nums[i] - ifor(int i = 0; i < n ;i++){b[i] -= i;}sort(b.begin(), b.end());b.erase(unique(b.begin(), b.end()), b.end()); //去重,得到了nums[i] - i离散化后的值就是iint m = b.size();vector<long long>tr(m + 1, LLONG_MIN);//树状数组function<void(int, long long)>update = [&](int x, long long val) -> void{for(int i = x; i < m + 1; i += bitset(i)){tr[i] = max(tr[i], val);}};function<long long(int)> pre_max = [&](int x) -> long long{long long res = LLONG_MIN;for(int i = x; i >= 1; i -= bitset(i)){res = max(res, tr[i]);}return res;};for(int i = 0;i < n; i++){//j是nums[i] - i离散化后的值,需要从1开始,因为使用了树状数组//每一次将nums[i]加入树状数组,先要找到其在b中对应的位置j。只有j之前的序列才满足条件int j = lower_bound(b.begin(), b.end(), nums[i] - i) - b.begin() + 1;long long f = max(0LL, pre_max(j)) + nums[i];//求以i结尾的子序列的前面最大的和update(j, f);}return pre_max(b.size());}
};

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

保障效率与可用,分析Kafka的消费者组与Rebalance机制

系列文章目录 上手第一关&#xff0c;手把手教你安装kafka与可视化工具kafka-eagle Kafka是什么&#xff0c;以及如何使用SpringBoot对接Kafka 架构必备能力——kafka的选型对比及应用场景 Kafka存取原理与实现分析&#xff0c;打破面试难关 防止消息丢失与消息重复——Kafka可…

mysql 全文检索 demo

mysql5.6.7之后开始支持中文全文检索一直没用过&#xff0c;这次试试。 创建表 CREATE TABLE articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,title VARCHAR (200),body TEXT,FULLTEXT (title, body) WITH PARSER ngram ) ENGINE INNODB DEFAULT CHARSETut…

享搭低代码平台:快速构建符合需求的进销存管理系统应用

本文介绍了享搭低代码平台如何赋予用户快速构建进销存管理系统应用的能力。通过在应用商店安装费用进销存管理模板&#xff0c;并通过拖拽方式对模板进行自定义扩充&#xff0c;用户可以快速搭建符合自身需求的进销存管理系统&#xff0c;从而提高管理效率和优化运营。 介绍低代…

Bash 4关联数组:错误“声明:-A:无效选项”

Bash 4 associative arrays: error “declare: -A: invalid option” 就是bash版本太低 1.先确定现在的版本 bash -version 我的就是版本太低 升级新版本bash4.2 即可 升级步骤 1.下载bash-4.2wget http://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz 2. 下载完成解压 tar -zxvf…

SQL注入之Sqli-labs第二关

本次注入sql-labs的第二关 1.进入第二关后&#xff0c;我们可以看到英语 please input the id as parameter with numeric value&#xff0c;请输入ID作为参数和数值。首先我们可以判断出这是一个GET请求作为注入点的题目&#xff0c;那么我们就需要去URL上拼接ID的值&#xff…

MMdetection3.x个人笔记

1.在自定义数据集用训练出的权重进行可视化推理 input(jpg文件) model_config 这两个可以不用加前面的形参 然后用 \ 隔开 写上 --weight xx.pth python demo/image_demo.py data/coco_duck/train2017/10640.jpg work_dirs/solov2_r50_fpn_1x_coco/solov2_r50_fpn_1x_coco…

嵌入式发展历史

MPU、MCU、SoC、Application Processors 在一个电子系统中&#xff0c;处理器占据最重要的位置&#xff0c;被称为中央处理器单元&#xff08;CPU&#xff1a;Central Processing Unit&#xff09;。它从IO设备读取数据&#xff0c;处理&#xff0c;然后输出。 CPU的发展历史…

IntelliJ IDEA Services工具栏运行不显示端口问题解决

问题 如Spring Boot服务启动时&#xff0c;端口不显示。 解决 1、 清理所有缓存 2、 关闭IntelliJ IDEA后&#xff0c;到C:\Users\&#xff08;你自己的用户名&#xff09;\AppData\Local\Temp路径把所有文件都删除&#xff0c;因为时一个缓存&#xff0c;不影响其他软件…

网络爬虫的实战项目:使用JavaScript和Axios爬取Reddit视频并进行数据分析

概述 网络爬虫是一种程序或脚本&#xff0c;用于自动从网页中提取数据。网络爬虫的应用场景非常广泛&#xff0c;例如搜索引擎、数据挖掘、舆情分析等。本文将介绍如何使用JavaScript和Axios这两个工具&#xff0c;实现一个网络爬虫的实战项目&#xff0c;即从Reddit这个社交媒…

SAP-MM-定义计量单位组

业务场景&#xff1a; 有些物料的计量单位是相同的&#xff0c;为了快速维护物料的计量单位的转换关系&#xff0c;可以创建计量单位组&#xff0c;输入转换关系时&#xff0c;输入组就可以直接转换&#xff0c;不需要单个维护 SPRO-后勤常规-物料主数据-设置关键字段-定义计…

MySQL数据库入门到大牛_02_MySQL环境搭建、演示使用、图形化管理工具、一二章练习

文章目录 1. MySQL的卸载步骤1&#xff1a;停止MySQL服务步骤2&#xff1a;软件的卸载步骤3&#xff1a;残余文件的清理步骤4&#xff1a;清理注册表&#xff08;选做&#xff09;步骤5&#xff1a;删除环境变量配置 2. MySQL的下载、安装、配置2.1 MySQL的4大版本2.2 软件的下…

性能优化之懒加载 - 基于观察者模式和单例模式的实现

一、引入 在前端性能优化中&#xff0c;关于图片/视频等内容的懒加载一直都是优化利器。当用户看到对应的视图模块时&#xff0c;才去请求加载对应的图像。 原理也很简单&#xff0c;通过浏览器提供的 IntersectionObserver - Web API 接口参考 | MDN (mozilla.org)&#xff0c…