力扣_2389. 和有限的最长子序列
给你一个长度为 n
的整数数组 nums
,和一个长度为 m
的整数数组 queries
。
返回一个长度为 m
的数组 answer
,其中 answer[i]
是 nums
中 元素之和小于等于 queries[i]
的 子序列 的 最大 长度 。
子序列 是由一个数组删除某些元素(也可以不删除)但不改变剩余元素顺序得到的一个数组。
示例 1:
输入:nums = [4,5,2,1], queries = [3,10,21]
输出:[2,3,4]
解释:queries 对应的 answer 如下:
- 子序列 [2,1] 的和小于或等于 3 。可以证明满足题目要求的子序列的最大长度是 2 ,所以 answer[0] = 2 。
- 子序列 [4,5,1] 的和小于或等于 10 。可以证明满足题目要求的子序列的最大长度是 3 ,所以 answer[1] = 3 。
- 子序列 [4,5,2,1] 的和小于或等于 21 。可以证明满足题目要求的子序列的最大长度是 4 ,所以 answer[2] = 4 。
示例 2:
输入:nums = [2,3,4,5], queries = [1]
输出:[0]
解释:空子序列是唯一一个满足元素和小于或等于 1 的子序列,所以 answer[0] = 0 。
提示:
n == nums.length
m == queries.length
1 <= n, m <= 1000
1 <= nums[i], queries[i] <= 106
我的思路是先对 nums 数组进行升序排序,使得我们能够通过累加最小的元素来逐步比较与查询值的关系。对每个查询值 queries[x] 进行处理,计算能被包含在该查询的最大子数组长度。通过逐步累加 nums 数组的元素,检查当前累积和是否小于等于查询值 queries[x]。如果满足条件,则更新 answer[x],并在无法满足条件时跳出内层循环。不过缺点是对于 m 较大时查询会变得比较慢。
class Solution {
public int[] answerQueries(int[] nums, int[] queries) {
// 获取 nums 数组的长度,n 表示数组 nums 的大小
int n = nums.length;
// 获取 queries 数组的长度,m 表示查询数组的大小
int m = queries.length;
// 初始化一个整数数组 answer 用来保存每个查询的答案,数组长度为 m
int[] answer = new int[m];
// 将 nums 数组进行升序排序
Arrays.sort(nums);
// 遍历每一个查询(queries 中的每个元素)
for (int x = 0; x < m; x++) {
// 初始化 sum 变量,用来计算当前累积的和
int sum = 0;
// 遍历 nums 数组中的每个元素并累加
for (int k = 0; k < n; k++) {
// 将当前元素 nums[k] 加到 sum 中
sum += nums[k];
// 如果当前累积和小于等于 queries[x],说明可以将前 k + 1 个数加起来
if (sum <= queries[x]) {
// 记录查询 x 对应的答案,k+1 是因为题目要求返回的是元素个数
answer[x] = k + 1;
} else {
// 如果累积和大于 queries[x],则说明无法将 k + 1 个数加起来
// 将答案设为 k,并跳出内层循环
answer[x] = k;
break;
}
}
}
// 返回包含每个查询结果的数组 answer
return answer;
}
}