6366. Number of Senior Citizens
给你一个下标从 0 开始的字符串 details 。details 中每个元素都是一位乘客的信息,信息用长度为 15 的字符串表示,表示方式如下:
- 前十个字符是乘客的手机号码。
- 接下来的一个字符是乘客的性别。
- 接下来两个字符是乘客的年龄。
- 最后两个字符是乘客的座位号。
请你返回乘客中年龄 严格大于 60 岁 的人数。测试样例
输入:details = ["7868190130M7522","5303914400F9211","9273338290F4010"]
输出:2
解释:下标为 0 ,1 和 2 的乘客年龄分别为 75 ,92 和 40 。所以有 2 人年龄大于 60 岁。
解答:这道题目就是寻找字符串的特定标志位(这里是第11和12位)。然后累加大于60的个数。
class Solution {
public int countSeniors(String[] details) {
int res = 0;
for (String d : details) {
int age = Integer.valueOf(d.substring(11, 11 + 2));
if (age > 60) ++res;
}
return res;
}
}
6367. Sum in a Matrix
给你一个下标从 0 开始的二维整数数组 nums 。一开始你的分数为 0 。你需要执行以下操作直到矩阵变为空:
- 矩阵中每一行选取最大的一个数,并删除它。如果一行中有多个最大的数,选择任意一个并删除。
- 在步骤 1 删除的所有数字中找到最大的一个数字,将它添加到你的 分数 中。
请你返回最后的 分数 。
测试样例:
输入:nums = [[7,2,1],[6,4,2],[6,5,3],[3,2,1]]
输出:15
解释:
第一步操作中,我们删除 7 ,6 ,6 和 3 ,将分数增加 7 。下一步操作中,删除 2 ,4 ,5 和 2 ,将分数增加 5 。最后删除 1 ,2 ,3 和 1 ,将分数增加 3 。所以总得分为 7 + 5 + 3 = 15 。
解答: 这道题目需要排序寻找每一行的最大值。然后依次搜索每一列的最大值并累加。
class Solution {
public int matrixSum(int[][] nums) {
int res = 0;
PriorityQueue<Integer>[] queues = new PriorityQueue[nums.length];
for (int i = 0; i < nums.length; ++i) {
queues[i] = new PriorityQueue<>((a, b) -> (b.compareTo(a)));
for (int n : nums[i]) {
queues[i].add(n);
}
}
for (int i = 0; i < nums[0].length; ++i) {
int max = -1;
for (int j = 0; j < nums.length; ++j) {
max = Math.max(max, queues[j].poll());
}
res += max;
}
return res;
}
}
6403. Maximum Number of Fish in a Grid
给你一个下标从 0 开始长度为 n 的整数数组 nums 和一个整数 k 。每一次操作中,你可以选择一个数并将它乘 2 。
你最多可以进行 k 次操作,请你返回 nums[0] | nums[1] | ... | nums[n - 1] 的最大值。
a | b 表示两个整数 a 和 b 的 按位或 运算。
测试样例:
输入:nums = [12,9], k = 1
输出:30
解答: 首先这道题目是一个贪婪算法。挑中一个数之后,所有k次都会用在这个数上(这样最大化二进制位的最大位)。由于是or操作,记录一下31位的情况,搜索每一个数的时候,就能知道排除当前数的累或情况。
class Solution {
public long maximumOr(int[] nums, int k) {
int[] count = new int[31];
for (int n : nums) {
for (int i = 0; i < 31; ++i) {
if (isMark(n, i)) {
count[i] += 1;
}
}
}
long res = 0;
for (int n : nums) {
long except = 0, tmp = n;
for (int i = 0; i < 31; ++i) {
int c = isMark(n, i) ? (count[i] - 1) : count[i];
if (c > 0) {
except += (1 << i);
}
}
res = Math.max(res, except | (tmp << k));
}
return res;
}
private boolean isMark(int n, int offset) {
int t = (n >> offset) & 1;
return t == 1;
}
}
6423. Power of Heroes
给你一个下标从 0 开始的整数数组 nums ,它表示英雄的能力值。如果我们选出一部分英雄,这组英雄的 力量 定义为:
- i0 ,i1 ,... ik 表示这组英雄在数组中的下标。那么这组英雄的力量为 max(nums[i0],nums[i1] ... nums[ik])2 * min(nums[i0],nums[i1] ... nums[ik]) 。
请你返回所有可能的 非空 英雄组的 力量 之和。由于答案可能非常大,请你将结果对 109 + 7 取余。
测试样例:
输入:nums = [2,1,4]
输出:141
- 第 1 组:[2] 的力量为 22 * 2 = 8 。
- 第 2 组:[1] 的力量为 12 * 1 = 1 。
- 第 3 组:[4] 的力量为 42 * 4 = 64 。
- 第 4 组:[2,1] 的力量为 22 * 1 = 4 。
- 第 5 组:[2,4] 的力量为 42 * 2 = 32 。
- 第 6 组:[1,4] 的力量为 42 * 1 = 16 。
- 第 7 组:[2,1,4] 的力量为 42 * 1 = 16 。
所有英雄组的力量之和为 8 + 1 + 64 + 4 + 32 + 16 + 16 = 141 。
解答:这道题目是真的泪目了。WA了2次。。。要仔细,累乘都能爆long的最大值。
题目本身其实不难,排序之后依次遍历就是min的出处。max的值为sum((2^i)(nums[i] nums[i]))
class Solution {
private static final int mod = 1_000_000_007;
public int sumOfPower(int[] nums) {
Arrays.sort(nums);
long res = 0, ini = 0;
long mul = 1;
for (int i = 1; i < nums.length; ++i) {
ini = add(ini, mul(mul, mul(nums[i], nums[i])));
mul = mul(mul, 2);
}
for (int i = 0; i < nums.length; ++i) {
res = add(res, mul(add(ini, mul(nums[i], nums[i])), nums[i]));
if (i + 1 < nums.length) {
ini = (ini - mul(nums[i + 1], nums[i + 1]) + mod) % mod;
}
ini = xDivY(ini);
}
return (int)(res);
}
private long add(long x, long b) {
return (x + b) % mod;
}
private long mul(long x, long b) {
return (x * b) % mod;
}
private long xDivY(long x) {
return (int)(inv2() * x % mod);
}
private long inv2() {
return 500000004L;
}
}
疯狂WA,最后一题需要仔细啊。