leetcode
leetcode 1801 ~ 1850
每一个查询的最大美丽值

每一个查询的最大美丽值

难度:

标签:

题目描述

代码结果

运行时间: 164 ms, 内存: 63.3 MB


/*
 * 思路:
 * 1. 使用 Java Stream 对 items 按价格升序排列。
 * 2. 使用 map 和 reduce 操作计算最大美丽值。
 * 3. 遍历 queries,使用二分查找找到每个查询对应的最大美丽值。
 */
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;

public class MaxBeautyStream {
    public int[] maximumBeauty(int[][] items, int[] queries) {
        // 对 items 按价格升序排列
        int[][] sortedItems = Arrays.stream(items)
                                    .sorted(Comparator.comparingInt(a -> a[0]))
                                    .toArray(int[][]::new);
        int n = queries.length;
        int[] answer = new int[n];
        int maxBeauty = 0;

        // 创建一个最大美丽值的数组
        int[] maxBeauties = new int[sortedItems.length];
        for (int i = 0; i < sortedItems.length; i++) {
            maxBeauty = Math.max(maxBeauty, sortedItems[i][1]);
            maxBeauties[i] = maxBeauty;
        }

        // 遍历 queries
        IntStream.range(0, n).forEach(i -> {
            int query = queries[i];
            // 二分查找找到价格小于等于 query 的最大美丽值
            int index = Arrays.binarySearch(sortedItems, new int[]{query + 1, 0}, Comparator.comparingInt(a -> a[0]));
            if (index < 0) index = -index - 2;
            answer[i] = index >= 0 ? maxBeauties[index] : 0;
        });

        return answer;
    }
}

解释

方法:

此题解采用了排序和二分搜索的方法来处理查询。首先,将items数组按照价格排序。随后,使用accumulate函数生成一个新的列表mx,其中mx[i]表示所有价格不超过items[i][0]的物品中的最大美丽值。这样做的目的是为每个价格点快速找到其对应的最大美丽值。对于每个查询,使用bisect_right在排序后的价格列表items中找出最大的索引,该索引对应的价格不超过查询值。最后,根据这个索引在mx中找到答案。

时间复杂度:

O(n log n + m log n)

空间复杂度:

O(n)

代码细节讲解

🦆
题解中提到首先对items按价格进行排序,排序后的items是否仍需保持原有的价格-美丽值对应关系?
是的,对items数组进行排序后,需要保持每个价格对应的美丽值不变。在排序过程中,每个元素(价格,美丽值对)被视为一个整体,排序仅改变它们在数组中的位置,而不改变价格和美丽值之间的关联。这样排序后,我们可以按价格顺序处理美丽值的累积最大值。
🦆
在使用accumulate函数计算最大美丽值列表mx时,为什么选择max作为累积函数?是否有其他函数或方法可以替代?
在此题目中,选择max作为累积函数是为了在给定价格范围内找到最大的美丽值。因为我们需要得到不超过某个价格的所有物品中的最大美丽值,使用max可以确保每步都取到目前为止遇到的最大美丽值。理论上,也可以通过手动比较和更新最大值来替代使用accumulate和max,但这将使代码更加复杂且容易出错。使用accumulate和max是一种更简洁和有效的方式。
🦆
题解中使用的bisect_right函数是如何确定不超过查询价格的最大索引的?在价格相同的情况下,该函数的表现如何?
bisect_right函数用于在已排序的列表中找到一个元素的插入点,使得插入后列表仍保持有序。在此题目中,它用来找到一个查询价格应该插入的位置索引,这个位置索引表示所有价格不超过查询价格的物品。在价格相同的情况下,bisect_right会返回最右边(即最后一个相同价格元素的后一个位置)的索引,确保包括所有具有相同价格的物品。
🦆
如果所有的items价格都高于某个查询值,mx列表中对应的返回值应该是多少?题解是否考虑到了这种边界情况?
题解中通过在accumulate函数使用initial=0参数考虑到了这种情况。如果所有的items价格都高于某个查询值,bisect_right将返回0,因为没有任何价格是小于或等于该查询价格的。因此,mx列表中索引0的值(由initial=0提供)将被返回,表示没有任何物品的价格低于该查询值,对应的最大美丽值为0。

相关问题