leetcode
leetcode 1401 ~ 1450
所有排列中的最大和

所有排列中的最大和

难度:

标签:

题目描述

代码结果

运行时间: 148 ms, 内存: 43.0 MB


/*
 * 思路:
 * 1. 对于每个请求区间,记录每个索引被请求的频率。
 * 2. 通过计算每个索引的请求次数,确定索引的权重。
 * 3. 将数组和权重排序,权重越大对应的数组值应越大。
 * 4. 将排序后的数组和权重一一对应相乘,得到最大查询和。
 * 5. 将结果对10^9 + 7取余后返回。
 */
import java.util.*;
import java.util.stream.*;

public class Solution {
    public int maxSumRangeQuery(int[] nums, int[][] requests) {
        int n = nums.length;
        int mod = 1000000007;
        int[] freq = new int[n];
        
        // 记录每个索引被请求的频率
        for (int[] req : requests) {
            freq[req[0]]++;
            if (req[1] + 1 < n) freq[req[1] + 1]--;
        }
        
        // 前缀和计算实际频率
        for (int i = 1; i < n; i++) {
            freq[i] += freq[i - 1];
        }
        
        // 排序
        Arrays.sort(nums);
        freq = Arrays.stream(freq).sorted().toArray();
        
        // 计算结果
        long result = 0;
        for (int i = 0; i < n; i++) {
            result = (result + (long) nums[i] * freq[i]) % mod;
        }
        
        return (int) result;
    }
}

解释

方法:

The solution utilizes a difference array to efficiently calculate the frequency of each index being accessed across all requests. First, it iterates through each request and updates the difference array to track the start and end+1 of each range. Then, by taking the prefix sum of this difference array, we get the number of times each index is accessed. After sorting this 'times' array and the 'nums' array in descending order, the product of corresponding elements from both arrays (the highest numbers with the highest frequencies) maximizes the sum. The result is then taken modulo 109 + 7.

时间复杂度:

O(n log n + m)

空间复杂度:

O(n)

代码细节讲解

🦆
在解决方案中使用差分数组的原因是什么?它如何帮助处理多个请求的索引频率?
差分数组是一种用于高效处理区间增减操作的数据结构。在本题中,每个请求定义了一个增加的区间,直接更新整个区间的每个元素将非常耗时,特别是当数组或请求列表很大时。使用差分数组,我们只需要在区间的开始位置增加一个值,在结束位置的下一个索引减去相同的值。这样,只有两个操作即可表示整个区间的更新。后续通过累积求和转换差分数组,就可以得到每个索引被访问的次数,这种方法大大提高了效率。
🦆
为什么在得到差分数组后要使用`accumulate`函数来计算每个索引被访问的次数?
差分数组中的每个元素代表了从当前位置开始,后续所有元素的增减值。使用`accumulate`函数(累积求和)可以将差分数组转换为原始的频次数组。具体来说,差分数组的每一点的变化通过累加传递到后面的所有点,最终形成了每个索引的实际访问次数。这是将局部修改信息扩展为全局访问频率的关键步骤。
🦆
排序`nums`和`times`数组时选择降序的理由是什么?如何保证这种方法可以得到最大的查询和?
将`nums`和`times`数组都按降序排序的目的是使得最大的数和最高的访问频率相乘,从而实现总和的最大化。具体来说,因为我们想最大化数组元素与其被访问次数的乘积之和,故将最大的元素配对最多的访问次数,可以确保每个乘积项尽可能大,进而使得总和最大。这种配对方式基于贪心算法的思想,是获得最大查询和的有效策略。
🦆
你的解决方案中提到了将结果对`10^9 + 7`取余,这样做的目的是什么?
取模运算`10^9 + 7`是一种常用的方法来防止整数溢出,并且这个数字是一个大的质数,常用于编程竞赛中避免极大数值的处理问题。在处理大量数据或大数乘法时,结果可能超过常规整数类型的存储范围,通过对一个大质数取余,我们可以保持结果在一个安全的数值范围内,同时也满足某些编程竞赛和算法应用的标准要求。

相关问题