[Leetcode Weekly Contest]317
链接:LeetCode
[Leetcode]2455. 可被三整除的偶数的平均值
给你一个由正整数组成的整数数组 nums ,返回其中可被 3 整除的所有偶数的平均值。
注意:n 个元素的平均值等于 n 个元素 求和 再除以 n ,结果 向下取整 到最接近的整数。
遍历即可,注意判空。
class Solution {
public int averageValue(int[] nums) {
int sum = 0, count = 0;
for(var num: nums) {
if((num & 1) == 0 && num%3 == 0) {
sum += num;
count ++;
}
}
return count == 0 ? 0 : sum/count;
}
}
[Leetcode]2456. 最流行的视频创作者
给你两个字符串数组 creators 和 ids ,和一个整数数组 views ,所有数组的长度都是 n 。平台上第 i 个视频者是 creator[i] ,视频分配的 id 是 ids[i] ,且播放量为 views[i] 。
视频创作者的 流行度 是该创作者的 所有 视频的播放量的 总和 。请找出流行度 最高 创作者以及该创作者播放量 最大 的视频的 id 。
- 如果存在多个创作者流行度都最高,则需要找出所有符合条件的创作者。
- 如果某个创作者存在多个播放量最高的视频,则只需要找出字典序最小的 id 。
返回一个二维字符串数组 answer ,其中 answer[i] = [creatori, idi] 表示 creatori 的流行度 最高 且其最流行的视频 id 是 idi ,可以按任何顺序返回该结果。
遍历即可。
class Solution {
public List<List<String>> mostPopularCreator(String[] creators, String[] ids, int[] views) {
HashMap<String, Long> scores = new HashMap<>();
HashMap<String, List<Integer>> indexes = new HashMap<>();
int n = creators.length;
for(int i=0;i<n;++i) {
scores.put(creators[i], scores.getOrDefault(creators[i], 0L) + views[i]);
indexes.computeIfAbsent(creators[i], k -> new ArrayList<Integer>()).add(i);
}
long mxVal = 0;
for(var val:scores.values()) mxVal = Math.max(mxVal, val);
List<List<String>> res = new ArrayList<List<String>>();
for(var creator:scores.keySet()) {
var result = new ArrayList<String>();
if(scores.get(creator) == mxVal) {
result.add(creator);
res.add(result);
}
}
for(int i=0;i<res.size();++i) {
var creatorList = res.get(i);
String mxViewInd = "";
int mxView = -1;
for(int ind:indexes.get(creatorList.get(0))) {
if(views[ind] > mxView) {
mxView = views[ind];
mxViewInd = ids[ind];
} else if(views[ind] == mxView && mxViewInd.compareTo(ids[ind]) > 0) {
mxViewInd = ids[ind];
}
}
creatorList.add(mxViewInd);
}
return res;
}
}
[Leetcode]2457. 美丽整数的最小增量
给你两个正整数 n 和 target 。
如果某个整数每一位上的数字相加小于或等于 target ,则认为这个整数是一个 美丽整数 。
找出并返回满足 n + x 是 美丽整数 的最小非负整数 x 。生成的输入保证总可以使 n 变成一个美丽整数。
贪心。基本思路是,不断 +1 直到产生进位,就可能让数位和变小。
代码实现时,可以直接计算每个数位进位后的结果。
比如 467,十位数进位为 470,百位数进位为 500,千位数进位为 1000(这一点在 \(\textit{target}=1\) 时尤为重要)。
class Solution {
public long makeIntegerBeautiful(long n, int target) {
//当 n = 9999_9999_9999L 时,数字位和最大,为 9*12=108
if (target >= 108)
return 0;
/*
* 12345 1
* n/10*10+10 12350
* n/100*100+100 12400
* n/1000*1000+1000 13000
* n/10000*10000+10000 20000
* n/100000*100000+100000 100000
* 1000000==n*10
*/
long i = 10;
long m = n;
do {
int sum = 0;
for (long j = m; j != 0; j /= 10)
sum += j % 10;
if (sum <= target)
return m - n;
m = m / i * i + i;
i *= 10;
} while (i != m * 10);
return m - n;
}
}
[Leetcode]2458. 移除子树后的二叉树高度
给你一棵 二叉树 的根节点 root ,树中有 n 个节点。每个节点都可以被分配一个从 1 到 n 且互不相同的值。另给你一个长度为 m 的数组 queries 。
你必须在树上执行 m 个 独立 的查询,其中第 i 个查询你需要执行以下操作:
从树中 移除 以 queries[i] 的值作为根节点的子树。题目所用测试用例保证 queries[i] 不 等于根节点的值。
返回一个长度为 m 的数组 answer ,其中 answer[i] 是执行第 i 个查询后树的高度。
注意:
- 查询之间是独立的,所以在每个查询执行后,树会回到其 初始 状态。
- 树的高度是从根到树中某个节点的 最长简单路径中的边数 。
DFS.先求出每棵子树的高度 \(\textit{height}\)(这里定义成最长路径的节点数)。
然后再 DFS 一遍这棵树,同时维护当前节点深度 \(\textit{depth}\)(从 0 开始),以及删除当前子树后剩余部分的树的高度 \(\textit{restH}\)(这里定义成最长路径的边数)。
class Solution {
private Map<TreeNode, Integer> height = new HashMap<>(); // 每棵子树的高度
private int[] res; // 每个节点的答案
public int[] treeQueries(TreeNode root, int[] queries) {
getHeight(root);
height.put(null, 0); // 简化 dfs 的代码,这样不用写 getOrDefault
res = new int[height.size()];
dfs(root, -1, 0);
for (var i = 0; i < queries.length; i++)
queries[i] = res[queries[i]];
return queries;
}
private int getHeight(TreeNode node) {
if (node == null) return 0;
var h = 1 + Math.max(getHeight(node.left), getHeight(node.right));
height.put(node, h);
return h;
}
private void dfs(TreeNode node, int depth, int restH) {
if (node == null) return;
++depth;
res[node.val] = restH;
dfs(node.left, depth, Math.max(restH, depth + height.get(node.right)));
dfs(node.right, depth, Math.max(restH, depth + height.get(node.left)));
}
}
参考:LeetCode