【每日一题Day282】LC2681英雄力量 | 排序+数学

英雄力量【LC2681】

给你一个下标从 0 开始的整数数组 nums ,它表示英雄的能力值。如果我们选出一部分英雄,这组英雄的 力量 定义为:

  • i0i1 ,… ik 表示这组英雄在数组中的下标。那么这组英雄的力量为 max(nums[i0],nums[i1] ... nums[ik])2 * min(nums[i0],nums[i1] ... nums[ik])

请你返回所有可能的 非空 英雄组的 力量 之和。由于答案可能非常大,请你将结果对 109 + 7 取余。

妙哉

  • 思路

    • 对于子序列而言,数组元素顺序不影响结果,因此先将数组排序

    • 枚举每个元素作为子序列的最小值,那么元素 n u m s [ i ] nums[i] nums[i]作为最小值的子序列的贡献为
      n u m s [ i ] ∗ ( n u m s [ i ] 2 + n u m s [ i + 1 ] 2 + 2 ∗ n u m s [ i + 2 ] 2 . . . + 2 n − i − 2 ∗ n u m s [ n − 1 ] ) = n u m s [ i ] 3 + n u m s [ i ] ∗ ( n u m s [ i + 1 ] 2 + 2 ∗ n u m s [ i + 2 ] 2 . . . + 2 n − i − 2 ∗ n u m s [ n − 1 ] ) = n u m s [ i ] 3 + p nums[i]*(nums[i]^2+nums[i+1]^2+2*nums[i+2]^2 ...+2^{n-i-2}*nums[n-1])\\ =nums[i]^3+nums[i]*(nums[i+1]^2+2*nums[i+2]^2 ...+2^{n-i-2}*nums[n-1])\\ =nums[i]^3+p nums[i](nums[i]2+nums[i+1]2+2nums[i+2]2...+2ni2nums[n1])=nums[i]3+nums[i](nums[i+1]2+2nums[i+2]2...+2ni2nums[n1])=nums[i]3+p

    • 实现时从右往左枚举左小指,先将 n u m s [ i ] 3 nums[i]^3 nums[i]3累加至结果,然后维护变量 p p p,每次将 n u m s [ i ] ∗ p nums[i]*p nums[i]p累加至结果,再令 p = p ∗ 2 + n u m s [ i ] 2 p= p *2+nums[i]^2 p=p2+nums[i]2

  • 实现

    class Solution {
        public int sumOfPower(int[] nums) {
            final int mod = (int) 1e9 + 7;
            Arrays.sort(nums);
            long ans = 0, p = 0;
            for (int i = nums.length - 1; i >= 0; --i) {
                long x = nums[i];
                ans = (ans + (x * x % mod) * x) % mod;
                ans = (ans + x * p % mod) % mod;
                p = (p * 2 + x * x % mod) % mod;
            }
            return (int) ans;
        }
    }
    
    作者:ylb
    链接:https://leetcode.cn/problems/power-of-heroes/solutions/2367175/python3javacgotypescript-yi-ti-yi-jie-pa-lgos/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 复杂度
      • 时间复杂度: O ( log ⁡ n ) \mathcal{O}(\log n) O(logn)
      • 空间复杂度: O ( n log ⁡ n ) \mathcal{O}(n \log n) O(nlogn)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值