题目要求计算数组所有非空子序列的宽度之和,其中宽度定义为子序列的最大值与最小值的差。由于子序列数量众多,直接枚举会超时,需要寻找更高效的方法。

关键思路:对数组排序后,每个元素
“nums[i]” 在多少个子序列中作为最大值或最小值出现。具体来说,排序后,
“nums[i]” 作为最大值的子序列个数为
“2^i”(因为比它小的
“i” 个元素每个可选可不选),作为最小值的子序列个数为
“2^(n-1-i)”(因为比它大的
“n-1-i” 个元素每个可选可不选)。那么,所有子序列的最大值之和为
“sum(nums[i] * 2^i)”,最小值之和为
“sum(nums[i] * 2^(n-1-i))”,两者相减即得结果。

算法步骤:

  1. 对数组排序。
  2. 预处理
    “2^i” 对
    “10^9+7” 取模的结果。
  3. 遍历数组,累加
    “nums[i] * (2^i - 2^(n-1-i))”。
  4. 返回结果,注意处理负数取模。

代码:

class Solution {
public int sumSubseqWidths(int[] nums) {
final int MOD = 1_000_000_007;
Arrays.sort(nums);
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 ans = 0;
for (int i = 0; i < n; i++) {
ans = (ans + nums[i] * (pow2[i] - pow2[n - 1 - i])) % MOD;
}
return (int) ((ans + MOD) % MOD);
}
}

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐