【力扣】2681. 英雄的力量

以下为他人题解思路,及本人代码

题目

题意

给你一个下标从 0 0 0 开始的整数数组 n u m s nums nums ,它表示英雄的能力值。如果我们选出一部分英雄,这组英雄的力量定义为:
i 0 , i 1 , . . . i k i_0 ,i_1 ,... i_k i0i1...ik 表示这组英雄在数组中的下标。那么这组英雄的力量为 m a x ( n u m s [ i 0 ] , n u m s [ i 1 ] . . . n u m s [ i k ] ) 2 ∗ m i n ( n u m s [ i 0 ] , n u m s [ i 1 ] . . . n u m s [ i k ] ) max(nums[i_0],nums[i_1] ... nums[i_k])2 * min(nums[i_0],nums[i_1] ... nums[i_k]) max(nums[i0],nums[i1]...nums[ik])2min(nums[i0],nums[i1]...nums[ik])
请你返回所有可能的非空英雄组的力量之和。由于答案可能非常大,请你将结果对 1 0 9 + 7 10^9 + 7 109+7 取余。

示例 1

输入 n u m s = [ 2 , 1 , 4 ] nums = [2,1,4] nums=[2,1,4]
输出 141 141 141
解释
1 1 1 组: [ 2 ] [2] [2] 的力量为 2 2 ∗ 2 = 8 2^2 * 2 = 8 222=8
2 2 2 组: [ 1 ] [1] [1] 的力量为 1 2 ∗ 1 = 1 1^2 * 1 = 1 121=1
3 3 3 组: [ 4 ] [4] [4] 的力量为 4 2 ∗ 4 = 64 4^2 * 4 = 64 424=64
4 4 4 组: [ 2 , 1 ] [2,1] [2,1] 的力量为 2 2 ∗ 1 = 4 2^2 * 1 = 4 221=4
5 5 5 组: [ 2 , 4 ] [2,4] [2,4] 的力量为 4 2 ∗ 2 = 32 4^2 * 2 = 32 422=32
6 6 6 组: [ 1 , 4 ] [1,4] [1,4] 的力量为 4 2 ∗ 1 = 16 4^2 * 1 = 16 421=16
第​ ​ ​ ​​​​​7 组: [ 2 , 1 , 4 ] [2,1,4] [2,1,4] 的力量为 4 2 ​​​​​​​ ∗ 1 = 16 4^2​​​​​​​ * 1 = 16 42​​​​​​​1=16
所有英雄组的力量之和为 8 + 1 + 64 + 4 + 32 + 16 + 16 = 141 8 + 1 + 64 + 4 + 32 + 16 + 16 = 141 8+1+64+4+32+16+16=141

示例 2

输入 n u m s = [ 1 , 1 , 1 ] nums = [1,1,1] nums=[1,1,1]
输出 7 7 7
解释:总共有 7 7 7 个英雄组,每一组的力量都是 1 1 1 。所以所有英雄组的力量之和为 7 7 7

提示

  1. 1 < = n u m s . l e n g t h < = 1 0 5 1 <= nums.length <= 10^5 1<=nums.length<=105
  2. 1 < = n u m s [ i ] < = 1 0 9 1 <= nums[i] <= 10^9 1<=nums[i]<=109

他人思路

贡献法

算法总结

由于元素的顺序不影响答案,先排序。

设有 a , b , c , d , e a,b,c,d,e a,b,c,d,e 五个数,顺序从小到大。

如果把 d d d 当成最大值:

  • 如果只选 d d d 单独一个数,那么力量为 d 3 d^3 d3
  • a a a 为最小值,由于中间的 b b b c c c 可选可不选,一共有 2 2 2^2 22 种方案,所以力量总和为 d 2 ∗ a ∗ 2 2 d^2 * a * 2^2 d2a22
  • b b b 为最小值,由于中间的 c c c 可选可不选,一共有 2 1 2^1 21 种方案,所以力量总和为 d 2 ∗ b ∗ 2 1 d^2 * b * 2^1 d2b21
  • c c c 为最小值,只有 2 0 = 1 2^0 = 1 20=1 种方案,所以力量总和为 d 2 ⋅ c ⋅ 2 0 d^2⋅c⋅2^0 d2c20

因此,当 d d d 为最大值时, d d d 及其左侧元素对答案的贡献为
d 3 + d 2 ∗ ( a ∗ 2 2 + b ∗ 2 1 + c ∗ 2 0 ) d^3 + d^2 * (a * 2^2 + b * 2^1 + c * 2^0) d3+d2(a22+b21+c20)

s = a ∗ 2 2 + b ∗ 2 1 + c ∗ 2 0 s = a * 2^2 + b * 2^1 + c * 2^0 s=a22+b21+c20,上式为
d 3 + d 2 ∗ s = d 2 ∗ ( d + s ) d^3 + d^2 * s = d^2 * (d + s) d3+d2s=d2(d+s)

继续,把 e e e 当成最大值,观察 s s s 如何变化,也就是 a , b , c , d a,b,c,d a,b,c,d 作为最小值的贡献:
a ∗ 2 3 + b ∗ 2 3 + c ∗ 2 1 + d ∗ 2 0 = 2 ∗ ( a ∗ 2 2 + b ∗ 2 1 + c ∗ 2 0 ) + d ∗ 2 0 = 2 ∗ s + d a * 2^3 + b * 2^3 + c * 2^1 + d * 2^0 \\= 2 * (a * 2^2 + b * 2^1 + c * 2^0) + d * 2^0 \\= 2 * s + d a23+b23+c21+d20=2(a22+b21+c20)+d20=2s+d

这意味着,我们不需要枚举最小值,只需要枚举最大值,就可以把 s s s 递推计算出来。

复杂度

  • 时间复杂度: O ( n l o g ⁡ n ) O(nlog⁡n) O(nlogn),其中 n n n n u m s nums nums 的长度。瓶颈在排序上。
  • 空间复杂度: O ( 1 ) O(1) O(1)。忽略排序的栈空间,仅用到若干额外变量。

本人代码

Java

class Solution {
    
    
    public int sumOfPower(int[] nums) {
    
    
        Arrays.sort(nums);

        long mod = (long) 1e9 + 7;
        long ans = 0, s = 0;
        for (long i : nums) {
    
    
            ans = (ans + i * i % mod * (i + s)) % mod;
            s = (2 * s + i) % mod;
        }

        return (int) ans;
    }
}

提交结果:通过

  • 执行用时: 14 m s 14ms 14ms
  • 内存消耗: 51.72 M B 51.72MB 51.72MB

猜你喜欢

转载自blog.csdn.net/qq_45256357/article/details/132051558