leetcode
leetcode 801 ~ 850
子序列宽度之和

子序列宽度之和

难度:

标签:

题目描述

代码结果

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


/*
 * 思路:
 * 1. 首先对数组进行排序。
 * 2. 计算每个元素作为最大值和最小值的贡献。
 * 3. 使用快速幂计算2的幂次。
 * 4. 计算所有子序列的宽度和。
 * 5. 最后对结果取模10^9 + 7。
 * 6. 使用Java Stream简化计算过程。
 */
import java.util.Arrays;
import java.util.stream.IntStream;

public class SolutionStream {
    public int sumSubseqWidths(int[] nums) {
        Arrays.sort(nums);
        long MOD = 1000000007;
        int n = nums.length;
        long[] pow2 = new long[n];
        pow2[0] = 1;
        for (int i = 1; i < n; i++) {
            pow2[i] = (pow2[i - 1] * 2) % MOD;
        }
        long result = IntStream.range(0, n).mapToLong(i -> (pow2[i] - pow2[n - 1 - i]) * nums[i] % MOD).sum() % MOD;
        return (int) result;
    }
}

解释

方法:

该题解首先对数组进行排序。排序后,对于排序数组中的任意两个元素x和y,如果x位于y之前,则在所有包含x和y的子序列中,x总是最小值,y总是最大值。利用这一特点,题解通过遍历排序后的数组来计算所有可能的子序列的宽度之和。具体实现中,题解使用zip函数将排序数组与其翻转后的自身进行配对,配对后的元组(x, y)中x总是小于等于y。每个配对元组对应的贡献是(x - y)乘以当前的2的幂次,这是因为数组中任一元素在子序列中出现的次数等于2的幂次(即该元素可以出现或不出现,有两种情况)。题解中用pow2变量来追踪2的幂次,每次迭代后都会更新这个值。最终结果对一个大数进行模运算,以防止溢出。

时间复杂度:

O(n log n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在计算宽度之和时需要将数组进行排序?排序的目的是什么?
在计算宽度之和时,排序的目的是为了方便确定任意两个元素在所有可能的子序列中的最小值和最大值的关系。排序后,对于任意两个元素x和y,如果x位于y之前(即x的索引小于y的索引),那么在所有包含x和y的子序列中,x总是最小值,y总是最大值。这种排序确保了在遍历和计算时,能够直接通过位置关系来判断元素的大小,简化了问题的复杂度。
🦆
在算法中,`pow2`变量的作用是什么?为什么要用`pow2 * 2 % MOD`更新它?
`pow2`变量表示2的幂次,用于计算每对元素(x, y)在所有子序列中的贡献次数。每个元素在子序列中出现的次数等于2的幂次,因为每个元素可以出现或不出现,有两种选择。使用`pow2 * 2 % MOD`更新是为了在每一步中计算下一个2的幂次,同时使用模运算防止数值过大导致整数溢出,保证计算结果的稳定性和准确性。
🦆
算法中使用`zip(nums, reversed(nums))`的意义是什么?这样配对的元素间的关系如何影响最终的宽度和?
使用`zip(nums, reversed(nums))`的意义在于直接获取排序后数组中位置对称的元素对,以便计算从数组两端到中心的每对元素的贡献。这样配对意味着对于数组中的每个元素,它在配对中一次作为最小值(与之后的元素配对),一次作为最大值(与之前的元素配对)。这种配对方式,使得计算宽度和时,可以有效地通过每对元素的差(x - y)乘以它们在子序列中的出现次数,来累加所有可能的子序列宽度。
🦆
题解中提到,每个配对元组的贡献是`(x - y) * pow2`,但通常我们期望x <= y,为什么这里使用x - y而不是y - x?
此处使用`(x - y) * pow2`的表达式是因为在`zip(nums, reversed(nums))`的配对中,第一个元素x总是从排序后的数组取,而第二个元素y是从数组的反向(即从大到小)取。因此,在每对配对中,x实际上是小于等于y的。这里使用x - y而不是y - x是因为在配对的表达式中,配对元素的顺序已经确保了x是较小的值,所以直接计算x - y可以得到负值或零,这符合求宽度(最大值减最小值)的目的。

相关问题