【LeetCode】第 370 场周赛

2023-11-06 00:20
文章标签 leetcode 周赛 370

本文主要是介绍【LeetCode】第 370 场周赛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

100115. 找到冠军 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 队将会是 冠军 。

返回这场比赛中将会成为冠军的队伍。


复杂度:O(N*N)
思路:用cnt记录每个人获胜的次数,哪名玩家的cnt更大,就将答案更新为那名玩家。

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

100116. 找到冠军 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 的有向边。
有向无环图 是不存在任何环的有向图。


复杂度:O(N)
思路:统计入度,更优化的。统计每个节点的前继节点,没有记为-1。若有多个-1,则将返回-1。

class Solution {public int findChampion(int n, int[][] edges) {int ans = -1;// 保存前继节点int[] pre = new int[n];Arrays.fill(pre, -1);int m = edges.length;for(int i=0; i<m; i++) {pre[edges[i][1]] = edges[i][0];}int cnt = 0;for(int i=0; i<n; i++) {if(pre[i] == -1) {cnt ++;if(cnt == 2) {return -1;}ans = i;}}return ans;}
}

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

有一棵 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 ,那么我们称这棵树是 健康的 。

你可以对这棵树执行任意次操作,但要求执行完所有操作以后树是 健康的 ,请你返回你可以获得的 最大分数 。


复杂度:O(N)
思路:DFS。原问题可以更换为:sum-每条路径上删去一个点。自底向上,统计删除子节点和删除根节点哪个成本更少。

class Solution {List<Integer>[] g;public long maximumScoreAfterOperations(int[][] edges, int[] values) {long ans = 0;for(int v:values) {ans += v;}int n = values.length;if(n == 2) {return Math.max(values[0], values[1]);}g = new ArrayList[n];// 存储后继节点Arrays.setAll(g, e-> new ArrayList());// 是否为根节点int[] cnt = new int[n];int m = edges.length;for(int[] e:edges) {int x = Math.min(e[0], e[1]);int y = Math.max(e[0], e[1]);g[x].add(y);g[y].add(x);     }     boolean[] visibled = new boolean[n]; // System.out.println(ans);return ans-dfs(g[0], 0, values, visibled, 0);}private long dfs(List<Integer> list, int idx, int[] values, boolean[] visibled, int l) {long ans = values[idx];int n = list.size();if(n == 1&&l!=0) return ans;l ++;long sum = 0;visibled[idx] = true;for(int i=0; i<n; i++) {// 获取后继索引int t = list.get(i);if(visibled[t] == false) {// System.out.println(idx+"-"+t);sum = sum + dfs(g[t], t, values, visibled, l);}            }return Math.min(sum, ans);}
}

100112. 平衡子序列的最大和

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

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

对于范围 [1, k - 1] 内的所有 j ,nums[ij] - nums[ij-1] >= ij - ij-1 都成立。
nums 长度为 1 的 子序列 是平衡的。

请你返回一个整数,表示 nums 平衡 子序列里面的 最大元素和 。

一个数组的 子序列 指的是从原数组中删除一些元素(也可能一个元素也不删除)后,剩余元素保持相对顺序得到的 非空 新数组。


复杂度:O(NlogN)
思路:
 ①将题目要求的条件改为num[i]-i为递增的。那么可以将num[i]-i按照从小到大的顺序离散到1-n。将nums[i]-i按照大小离散化到1-n。
 ②DP。dp[i]表示前i个元素的子序列和的最大值。
dp[i] = Math.max(dp[j])+nums[i]。j<i且nums[j]<=nums[i]
 ③使用树状数组实现dp[i]。由于nums[i]-i被按照大小离散化到1-j-n。所以只要搜寻j之前的元素即可。这部分使用preMax函数实现。
更新树状数组时,由于记录的已经是前缀和,直接按照大小更新。

在这里插入图片描述

class Solution {long minN = Long.MIN_VALUE;// 树状数组class BIT{// 数组private long[] tree;public BIT(int n) {tree = new long[n];Arrays.fill(tree, minN);}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 = minN;while(i>0) {res = Math.max(res, tree[i]);i -= i&-i;}return res;}}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;}long ans = minN;Arrays.sort(b);BIT tree = new BIT(n+1);for(int i=0; i<n; i++) {// 离散区间int j = Arrays.binarySearch(b, nums[i]-i)+1;long f = Math.max(tree.preMax(j), 0) + nums[i];ans = Math.max(ans, f);tree.update(j, f);}return ans;}
}

这篇关于【LeetCode】第 370 场周赛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/353395

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

【JavaScript】LeetCode:21-25

文章目录 21 最大子数组和22 合并区间23 轮转数组24 除自身以外数组的乘积25 缺失的第一个正数 21 最大子数组和 贪心 / 动态规划贪心:连续和(count)< 0时,放弃当前起点的连续和,将下一个数作为新起点,这里提供使用贪心算法解决本题的代码。动态规划:dp[i]:以nums[i]为结尾的最长连续子序列(子数组)和。 dp[i] = max(dp[i - 1]