6315. Count the Number of Vowel Strings in Range
给你一个下标从 0 开始的字符串数组 words 和两个整数:left 和 right 。
如果字符串以元音字母开头并以元音字母结尾,那么该字符串就是一个 元音字符串 ,其中元音字母是 'a'、'e'、'i'、'o'、'u' 。
返回 words[i] 是元音字符串的数目,其中 i 在闭区间 [left, right] 内。
测试样例
输入:words = ["are","amy","u"], left = 0, right = 2
输出:2
解答:按照题意hard code
class Solution {
private static final char[] vowels = {'a','e','i','o','u'};
public int vowelStrings(String[] words, int left, int right) {
int res = 0;
for (int i = left; i <= right; ++i) {
if (isVowel(words[i].charAt(0)) && isVowel(words[i].charAt(words[i].length() - 1))) {
++res;
}
}
return res;
}
private boolean isVowel(char c) {
for (char v : vowels) {
if (c == v) return true;
}
return false;
}
}
6316. Rearrange Array to Maximize Prefix Score
给你一个下标从 0 开始的整数数组 nums 。你可以将 nums 中的元素按 任意顺序 重排(包括给定顺序)。
令 prefix 为一个数组,它包含了 nums 重新排列后的前缀和。换句话说,prefix[i] 是 nums 重新排列后下标从 0 到 i 的元素之和。nums 的 分数 是 prefix 数组中正整数的个数。
返回可以得到的最大分数。
测试样例:
输入:nums = [2,-1,0,1,-3,3,-3]
输出:6
解释:
数组重排为 nums = [2,3,1,-1,-3,0,-3] 。prefix = [2,5,6,5,2,2,-1] ,分数为 6 。可以证明 6 是能够得到的最大分数。
解答: 倒序排序计算为正数的前缀和。我的代码就是顺序排序,计算后缀和。
class Solution {
public int maxScore(int[] nums) {
Arrays.sort(nums);
long sum = 0;
int res = 0;
for (int i = nums.length - 1; i >= 0; --i) {
sum += nums[i];
if (sum > 0) {
++res;
}
}
return res;
}
}
6317. Count the Number of Beautiful Subarrays
给你一个下标从 0 开始的整数数组nums 。每次操作中,你可以:
- 选择两个满足 0 <= i, j < nums.length 的不同下标 i 和 j 。
- 选择一个非负整数 k ,满足 nums[i] 和 nums[j] 在二进制下的第 k 位(下标编号从 0 开始)是 1 。
- 将 nums[i] 和 nums[j] 都减去 2k 。
如果一个子数组内执行上述操作若干次后,该子数组可以变成一个全为 0 的数组,那么我们称它是一个 美丽 的子数组。
请你返回数组 nums 中 美丽子数组 的数目。
子数组是一个数组中一段连续 非空 的元素序列。
测试样例
输入:nums = [4,3,1,2,4]
输出:2
解释:
nums 中有 2 个美丽子数组:[4,3,1,2,4] 和 [4,3,1,2,4] 。
- 按照下述步骤,我们可以将子数组 [3,1,2] 中所有元素变成 0 :
- 选择 [3, 1, 2] 和 k = 1 。将 2 个数字都减去 21 ,子数组变成 [1, 1, 0] 。
- 选择 [1, 1, 0] 和 k = 0 。将 2 个数字都减去 20 ,子数组变成 [0, 0, 0] 。
- 按照下述步骤,我们可以将子数组 [4,3,1,2,4] 中所有元素变成 0 :
- 选择 [4, 3, 1, 2, 4] 和 k = 2 。将 2 个数字都减去 22 ,子数组变成 [0, 3, 1, 2, 0] 。
- 选择 [0, 3, 1, 2, 0] 和 k = 0 。将 2 个数字都减去 20 ,子数组变成 [0, 2, 0, 2, 0] 。
- 选择 [0, 2, 0, 2, 0] 和 k = 1 。将 2 个数字都减去 21 ,子数组变成 [0, 0, 0, 0, 0] 。
解答:这道题目是前缀和+计算差值的一个变形。如果能成为一个美丽子数组,则二进制所有位出现次数都是偶数次。换言之,每一位mod值为0。
所以我们可以利用一个Integer来记录每一位的情况,然后用Map记录一下结果就可以了。
class Solution {
public long beautifulSubarrays(int[] nums) {
HashMap<Integer, Integer> mem = new HashMap<>();
mem.put(0, 1);
int key = 0;
long res = 0;
for (int n : nums) {
for (int i = 0; i < 31; ++i) {
if (isMark(n, i)) {
key = changePos(key, i);
}
}
int tmp = mem.getOrDefault(key, 0);
res += tmp;
mem.put(key, tmp + 1);
}
return res;
}
private boolean isMark(int n, int o) {
int t = (n >> o) & 1;
return t == 1;
}
private int changePos(int n, int o) {
int t = (n >> o) & 1;
if (t == 0) {
n += (1 << o);
} else {
n -= (1 << o);
}
return n;
}
}
6318. Minimum Time to Complete All Tasks
你有一台电脑,它可以 同时 运行无数个任务。给你一个二维整数数组 tasks ,其中 tasks[i] = [starti, endi, durationi] 表示第 i 个任务需要在 闭区间 时间段 [starti, endi] 内运行 durationi 个整数时间点(但不需要连续)。
当电脑需要运行任务时,你可以打开电脑,如果空闲时,你可以将电脑关闭。
请你返回完成所有任务的情况下,电脑最少需要运行多少秒。
测试样例
输入:tasks = [[2,3,1],[4,5,1],[1,5,2]]
输出:2
解释:
- 第一个任务在闭区间 [2, 2] 运行。
- 第二个任务在闭区间 [5, 5] 运行。
- 第三个任务在闭区间 [2, 2] 和 [5, 5] 运行。
电脑总共运行 2 个整数时间点。
解答:按照任务结束时间排序,那么越晚让计算机启动,所能够覆盖的任务越是多。注意提示给的范围:
- 1 <= tasks.length <= 2000
- 1 <= starti, endi <= 2000
直接暴力运算就可以了
class Solution {
public int findMinimumTime(int[][] tasks) {
Arrays.sort(tasks, (a, b) -> (a[1] - b[1]));
boolean[] isTaken = new boolean[2001];
int res = 0;
for (int[] task : tasks) {
for (int i = task[0]; i <= task[1]; ++i) {
if (isTaken[i]) {
task[2] -= 1;
}
}
if (task[2] > 0) {
for (int i = task[1]; i >= task[0]; --i) {
if (!isTaken[i]) {
isTaken[i] = true;
task[2] -= 1;
++res;
if (task[2] == 0) break;
}
}
}
}
return res;
}
}