leetcode
leetcode 2351 ~ 2400
最大和查询

最大和查询

难度:

标签:

题目描述

You are given two 0-indexed integer arrays nums1 and nums2, each of length n, and a 1-indexed 2D array queries where queries[i] = [xi, yi].

For the ith query, find the maximum value of nums1[j] + nums2[j] among all indices j (0 <= j < n), where nums1[j] >= xi and nums2[j] >= yi, or -1 if there is no j satisfying the constraints.

Return an array answer where answer[i] is the answer to the ith query.

 

Example 1:

Input: nums1 = [4,3,1,2], nums2 = [2,4,9,5], queries = [[4,1],[1,3],[2,5]]
Output: [6,10,7]
Explanation: 
For the 1st query xi = 4 and yi = 1, we can select index j = 0 since nums1[j] >= 4 and nums2[j] >= 1. The sum nums1[j] + nums2[j] is 6, and we can show that 6 is the maximum we can obtain.

For the 2nd query xi = 1 and yi = 3, we can select index j = 2 since nums1[j] >= 1 and nums2[j] >= 3. The sum nums1[j] + nums2[j] is 10, and we can show that 10 is the maximum we can obtain. 

For the 3rd query xi = 2 and yi = 5, we can select index j = 3 since nums1[j] >= 2 and nums2[j] >= 5. The sum nums1[j] + nums2[j] is 7, and we can show that 7 is the maximum we can obtain.

Therefore, we return [6,10,7].

Example 2:

Input: nums1 = [3,2,5], nums2 = [2,3,4], queries = [[4,4],[3,2],[1,1]]
Output: [9,9,9]
Explanation: For this example, we can use index j = 2 for all the queries since it satisfies the constraints for each query.

Example 3:

Input: nums1 = [2,1], nums2 = [2,3], queries = [[3,3]]
Output: [-1]
Explanation: There is one query in this example with xi = 3 and yi = 3. For every index, j, either nums1[j] < xi or nums2[j] < yi. Hence, there is no solution. 

 

Constraints:

  • nums1.length == nums2.length 
  • n == nums1.length 
  • 1 <= n <= 105
  • 1 <= nums1[i], nums2[i] <= 109 
  • 1 <= queries.length <= 105
  • queries[i].length == 2
  • xi == queries[i][1]
  • yi == queries[i][2]
  • 1 <= xi, yi <= 109

代码结果

运行时间: 152 ms, 内存: 64.5 MB


/*
 * 思路:
 * 使用 Java Stream API 优化代码,实现同样的逻辑。
 */
import java.util.stream.IntStream;

public int[] maxSumQueries(int[] nums1, int[] nums2, int[][] queries) {
    return IntStream.range(0, queries.length).map(i -> {
        int x = queries[i][0];
        int y = queries[i][1];
        return IntStream.range(0, nums1.length)
                        .filter(j -> nums1[j] >= x && nums2[j] >= y)
                        .map(j -> nums1[j] + nums2[j])
                        .max()
                        .orElse(-1);
    }).toArray();
}

解释

方法:

这个题解首先将nums1和nums2的每个元素对应相加,并与原始值一同存储,然后对这个组合列表按照和的降序进行排序。对于每个查询,通过一个缓存的函数`query`来处理,该函数遍历排序后的列表,检查每个元素是否满足查询条件,返回满足条件的最大和或-1。由于列表是按和排序的,因此一旦和小于xi和yi的和,就可以直接返回-1,提高了效率。

时间复杂度:

O(n log n + q * n)

空间复杂度:

O(n + q)

代码细节讲解

🦆
在题解中,你是如何确定将nums1和nums2的元素对应相加后进行排序是一个有效的优化步骤?
将nums1和nums2的元素相加得到的和可以直接代表两个数组中相应位置的元素的总体贡献。通过对这些和进行排序,我们可以快速定位到可能的最大和。当处理查询时,排序后的数组可以让我们从最大可能和开始检查,这样一旦找到第一个满足条件的和,即可确定为最大和。这种方式避免了从小到大逐个检查每个组合的低效率,尤其是在和较大或对和的要求较高的情况下,可以显著减少必要的比较次数。
🦆
题解中提到使用缓存来优化处理查询的步骤,具体是如何实现的?请解释这种方法如何减少计算重复度?
在题解中,使用了Python的装饰器`@cache`来缓存`query`函数的结果。这意味着每一次对于相同的x和y值的查询结果会被存储起来,当再次遇到相同的查询时,可以直接从缓存中获取答案而不需要重新计算。这种方法在处理多个重复查询时非常有效,因为它避免了对于同一查询条件的重复计算,从而提高了算法的整体效率。
🦆
题解中提到一旦当前和小于查询的x+y就可以返回-1,这种提前停止的逻辑是基于什么假设或保证?
这种逻辑是基于数组已经按照和的降序排列的事实。如果在遍历过程中遇到一个和小于查询的x+y,由于后续的和只会更小,因此不可能存在一个更大的和满足查询条件。这使得算法可以在确认无法找到满足条件的和时立即停止,从而节省时间,避免无效的计算。
🦆
排序后的列表遍历检查是否满足查询条件时,如果不满足条件直接返回-1,这是否意味着排序后的列表中所有后续的元素都不会满足条件?请解释原因。
这个问题的答案取决于不满足条件的具体情况。如果当前元素的和已经小于查询的x+y,则由于列表是降序的,后续的所有元素的和都会更小,因此不可能满足条件。但如果当前元素的和足够大,但是其nums1或nums2的值不满足x或y的要求,则无法立即断定后续元素也不满足条件,因为可能存在后续的其他元素虽然和较小,但具体的nums1或nums2的值可能满足条件。

相关问题