leetcode周赛 第 370 场周赛

news2024/11/25 12:23:57

2923. 找到冠军 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 == grid.length
  • n == grid[i].length
  • 2 <= n <= 100
  • grid[i][j] 的值为 0 或 1
  • 对于满足 i != j 的所有 i, j ,grid[i][j] != grid[j][i] 均成立
  • 生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

思路:

每个队伍都会比一次,一定会有一个答案,那么其实就很简单了,直接两层循环,直接判断哪个队伍胜场为n-1,哪个就是冠军。

class Solution {
    public int findChampion(int[][] grid) {
        int ans = 0;
        int n = grid.length;
        for (int i=0;i<n;i++) {
            int cnt = 0;
            for (int j=0;j<n;j++) {
                if (i != j) {
                    if (grid[i][j] == 1) cnt +=1;
                }
            }
            if (cnt == n-1) {
                ans = i;
                break;
            }
        }
        return ans;
    }
}

2924. 找到冠军 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
  • m == edges.length
  • 0 <= m <= n * (n - 1) / 2
  • edges[i].length == 2
  • 0 <= edge[i][j] <= n - 1
  • edges[i][0] != edges[i][1]
  • 生成的输入满足:如果 a 队比 b 队强,就不存在 b 队比 a 队强
  • 生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

思路:

因为冠军的队伍不止一个,并且是有向的,那其实就可以直接用入度出度的即可。只要没有败场的队伍,那就是冠军。说白了,其实就是入度为0的队伍,遍历一遍即可。

class Solution {
    public int findChampion(int n, int[][] edges) {
        int[] ru = new int[n];
        int m = edges.length;
        for (int i=0;i<m;i++) {
            ru[edges[i][1]] += 1;
        }
        int ans = 0;
        int cnt = 0;
        for (int i=0;i<n;i++) {
            if (ru[i] == 0) {
                ans = i;
                cnt += 1;
            }
        }
        if (cnt == 1) return ans;
        else return -1;
    }
}

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

有一棵 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 * 10^4
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • values.length == n
  • 1 <= values[i] <= 10^9
  • 输入保证 edges 构成一棵合法的树。

思路:

一开始题目没看清楚……我以为是有向树,也没看到根节点是0…

这道题目用到的算法主要是用到了树形DP,其实我们可以用简单的例子看看如何选择。

正难则反,先把所有 values[i] 加到答案中,然后考虑哪些 values[i] 不能选(撤销,不加入答案)。

设当前节点为 x,计算以 x 为根的子树是健康时,失去的最小分数。那么答案就是 values 的元素和,减去「以 0 为根的子树是健康时,失去的最小分数」。

用「选或不选」分类讨论:

第一种情况:失去 values[x],也就是不加入答案,那么 x 的所有子孙节点都可以加入答案,失去的最小分数就是 values[x]。
第二种情况:values[x] 加入答案,问题变成「以 y 为根的子树是健康时,失去的最小分数」,这里 y 是 x 的儿子。如果有多个儿子,累加失去的最小分数。
这两种情况取最小值。注意第一种情况是不会往下递归的,所以当我们递归到叶子的时候,叶子一定不能加入答案,此时直接返回 values[x]。

代码实现时,为了方便判断 x 是否为叶子节点,可以假设还有一条 0 到 −1 的边,这样不会误把根节点 0 当作叶子。

我的代码又臭又长(给大家看看笑话就行)。。。

class Solution {
    // 将一些变量直接放入类变量
    private ArrayList<ArrayList<Integer>> mp = new ArrayList<ArrayList<Integer>>();
    private int[] v;
    public long maximumScoreAfterOperations(int[][] edges, int[] values) {
        v = values;
        mp.clear();
        int n = edges.length + 1;
        for(int i=0;i<n;i++) {
            ArrayList<Integer> tmp = new ArrayList<Integer>();
            mp.add(tmp);
        }
        for (int i=0;i<n-1;i++) {
            // 双向图
            ArrayList<Integer> tmp = mp.get(edges[i][0]);
            tmp.add(edges[i][1]);
            ArrayList<Integer> t = mp.get(edges[i][1]);
            t.add(edges[i][0]);
        }
        long[] ans = dfs(0, -1);
        return ans[0];
    }
    // long数组第一个元素表示当前节点的最大价值和,第二个元素是当前节点的sum
    public long[] dfs(int root, int last) {
        ArrayList<Integer> tmp = mp.get(root);
        int n = tmp.size();
        if (n == 1 && last != -1) {
            // 如果是叶子结点
            long[] t = new long[2];
            t[0] = 0;
            t[1] = v[root];
            return t;
        }
        long[][] child = new long[n][2];
        long sum = 0;
        long res = 0;
        for (int i=0;i<n;i++) {
            if (tmp.get(i) == last) continue;
            child[i] = dfs(tmp.get(i), root);
            sum += child[i][1];
            res += child[i][0];
        }
        long cnt = 0 ;
        for (int i=0;i<n;i++) {
            cnt += child[i][0];
        }
        cnt += v[root];
        long[] t = new long[2];
        // 所有子节点的sum,除去了最小的代价
        if (cnt >= sum) {
            t[0] = cnt;
            t[1] = sum + v[root];
            
        } else {
            t[0] = sum;
            t[1] = sum + v[root];
        }
        return t;
    }
}

人家的代码:

class Solution {
    public long maximumScoreAfterOperations(int[][] edges, int[] values) {
        List<Integer>[] g = new ArrayList[values.length];
        Arrays.setAll(g, e -> new ArrayList<>());
        g[0].add(-1); // 避免误把根节点当作叶子
        for (int[] e : edges) {
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }

        // 先把所有分数加入答案
        long ans = 0;
        for (int v : values) {
            ans += v;
        }
        return ans - dfs(0, -1, g, values);
    }

    // dfs(x) 计算以 x 为根的子树是健康时,失去的最小分数
    private long dfs(int x, int fa, List<Integer>[] g, int[] values) {
        if (g[x].size() == 1) { // x 是叶子
            return values[x];
        }
        long loss = 0; // 第二种情况
        for (int y : g[x]) {
            if (y != fa) {
                loss += dfs(y, x, g, values); // 计算以 y 为根的子树是健康时,失去的最小分数
            }
        }
        return Math.min(values[x], loss); // 两种情况取最小值
    }
}

2926. 平衡子序列的最大和

给你一个下标从 0 开始的整数数组 nums 。

nums 一个长度为 k 的 子序列 指的是选出 k 个 下标 i0 < i1 < ... < ik-1 ,如果这个子序列满足以下条件,我们说它是 平衡的 :

  • 对于范围 [1, k - 1] 内的所有 j ,nums[ij] - nums[ij-1] >= ij - ij-1 都成立。

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 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9

思路:

https://leetcode.cn/problems/maximum-balanced-subsequence-sum/

写不出来,直接给个链接先了。。。

class Solution {
    public long maxBalancedSubsequenceSum(int[] nums) {
        int n = nums.length;
        int[] b = new int[n];
        for (int i = 0; i < n; i++) {
            b[i] = nums[i] - i;
        }
        Arrays.sort(b);
 
        BIT t = new BIT(b.length + 1);
        for (int i = 0; i < n; i++) {
            // j 为 nums[i]-i 离散化后的值(从 1 开始)
            int j = Arrays.binarySearch(b, nums[i] - i) + 1;
            long f = Math.max(t.preMax(j), 0) + nums[i];
            t.update(j, f);
        }
        return t.preMax(b.length);
    }
}

// 树状数组模板(维护前缀最大值)
class BIT {
    private long[] tree;

    public BIT(int n) {
        tree = new long[n];
        Arrays.fill(tree, Long.MIN_VALUE);
    }

    public void update(int i, long val) {
        while (i < tree.length) {
            tree[i] = Math.max(tree[i], val);
            i += i & -i;
        }
    }

    public long preMax(int i) {
        long res = Long.MIN_VALUE;
        while (i > 0) {
            res = Math.max(res, tree[i]);
            i &= i - 1;
        }
        return res;
    }
}

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

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

相关文章

第五章:java构造方法与对象创建

系列文章目录 文章目录 系列文章目录前言一、构造方法&#xff08;构造器&#xff09;二、对象创建流程总结 前言 构造方法由程序自动调用&#xff0c;完成对象初始化。 一、构造方法&#xff08;构造器&#xff09; 构造方法又叫构造器(constructor)&#xff0c; 是类的一种…

将字符串转换为日期型对象date.fromisoformat(str)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将字符串转换为日期型对象 date.fromisoformat(str) 选择题 下列代码执行后&#xff0c;变量d的数据类型是? s 2023-11-01 d date.fromisoformat(s) print(f"【显示】s {s}") p…

大数据毕业设计选题推荐-家具公司运营数据分析平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

SLAM从入门到精通(车道线检测)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于slam而言&#xff0c;大家一般想到的就是去通过传感器找特征点&#xff0c;进而借助于特征点去定位机器人的位置。但是对于用户或者厂家来说&a…

Linux常用命令——cd命令

在线Linux命令查询工具 cd 切换用户当前工作目录 补充说明 cd命令用来切换工作目录至dirname。 其中dirName表示法可为绝对路径或相对路径。若目录名称省略&#xff0c;则变换至使用者的home directory(也就是刚login时所在的目录)。另外&#xff0c;~也表示为home directo…

LabVIEW开发多速率实时混合仿真

LabVIEW开发多速率实时混合仿真 混合仿真是一种子结构技术&#xff0c;通过将数值建模的优点与实验测试的优点相结合来模拟感兴趣的结构。模拟结构的其余部分特别令人感兴趣&#xff0c;因此可以进行物理复制&#xff0c;以揭示粘弹性、屈曲、速率相关特性或其他非线性效应的影…

微信小程序文件上传wx.uploadFile

网页版查看了一下负载要求是这样 wx.uploadFile({url: ${wx.getStorageSync(apiUrl)}//sysFileInfo/upload?token${wx.getStorageSync(token)}, // 仅为示例&#xff0c;非真实的接口地址filePath: files[0].url,name: file,formData: {secretFlag: Y },success: (res) > {…

Android 11.0 framework层实现app默认全屏显示

1.前言 在11.0的系统rom定制化开发中,在对于第三方app全屏显示的功能需求开发中,需要默认app全屏显示,针对这一个要求,就需要在系统启动app 的过程中,在绘制app阶段就设置全屏属性,接下来就实现这个功能 效果图如下: 2.framework层实现app默认全屏显示的核心类 framewo…

数据跨领域应用实例—公路数据应用场景(一)

2023年10月25日&#xff0c;国家数据局正式揭牌。标志着我国数据基础制度正在不断完善&#xff0c;数据资源使用水平稳额步提升&#xff0c;数据要素市场将进入发展快车道。当前&#xff0c;数字经济已成为我国经济高质量发展的新动能&#xff0c;国家数据局的成立&#xff0c;…

数量关系(蒙题技巧)

选中间2项 选三的倍数 数学中很少无法确定 难题 质数很难消掉

Leetcode Daily Challenge 1845. Seat Reservation Manager

1845. Seat Reservation Manager 题目要求&#xff1a;初始化一个SeatManager类包括默认构造函数和类函数&#xff0c;所有的seat初始化为true。reverse函数返回最小的true&#xff0c;然后把这个编号的椅子赋值为false。unreverse(seatNumber)函数把编号为seatNumber的椅子恢…

OpenAI 发布会总结-图片版

关于OpenAI发布会的总结&#xff0c;这里开一个帖子 汇总精华的展示图&#xff0c;以便大家理解&#xff1a; 2 产品 3、价格分析

volatile-日常使用场景

6.4 如何正确使用volatile 单一赋值可以&#xff0c;但是含复合运算赋值不可以&#xff08;i之类的&#xff09; volatile int a 10; volatile boolean flag true; 状态标志&#xff0c;判断业务是否结束 作为一个布尔状态标志&#xff0c;用于指示发生了一个重要的一次…

001、Nvidia Jetson Nano Developer KIT(b01)

之——镜像烧录 杂谈 Nvidia Jetson Nano Developer KIT&#xff08;b01&#xff0c;4G&#xff09;&#xff0c;系统配置全纪录&#xff0c;镜像烧录、系统安装、远程桌面安装、cuda与torch安装、pycharm、pycuda、tensorrt等等。 正文 1.开发板系统安装 1.1 开发板简介 Jet…

【框架篇】统一数据格式返回

✅作者简介&#xff1a;大家好&#xff0c;我是小杨 &#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 1&#xff0c;统一数据格式返回的介绍 统一数据返回是指在进行接口开发时对返回数据进行规范和统…

【MogDB/openGauss的三种函数稳定性关键字】

一、ORACLE中的类似的函数稳定性关键字&#xff08;DETERMINISTIC&#xff09; 在ORACLE里&#xff0c;function有着一个DETERMINISTIC参数&#xff0c;它表示一个函数在输入不变的情况下输出是否确定&#xff0c;只要输入的参数一样&#xff0c;返回的结果一定一样的&#xf…

Android Mvp案例解析

目录 后端数据接口数据格式 App客户端布局逻辑主界面布局 M&#xff08;Model&#xff09;V&#xff08;View&#xff09;P&#xff08;Presenter&#xff09;OkhttpRetrofitRxJava网络http请求 Mvp架构-初学者MVP架构的契约者 后端数据接口 接口地址&#xff1a;https://apis.…

APP埋点:页面统计与事件统计

我们平时所说的埋点&#xff0c;可以大致分为两部分&#xff0c;一部分是统计APP页面访问情况&#xff0c;即页面统计&#xff1b;另外一部分是统计APP内的操作行为&#xff0c;及自定义事件统计。 一、页面统计 页面统计&#xff0c;可以统计应用内各个页面的访问次数&#x…

fiddler抓包拦截请求转发到其他地址

使用Fiddler拦截请求转发到指定地址方便于本地调试&#xff0c;不需要进行打包切换地址&#xff0c;可以加快问题的确定修复效果 内容&#xff1a; 1&#xff1a;首先给app进行设置代理抓包内容&#xff0c;给进行 https://blog.csdn.net/qq_43717814/article/details/84317038…

精读《算法题 - 二叉树中的最大路径和》

今天我们看一道 leetcode hard 难度题目&#xff1a;二叉树中的最大路径和。 题目 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点…