【每日一题Day31】LC891子序列宽度之和 | 数学

子序列宽度之和【LC891】

一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。

给你一个整数数组 nums ,返回 nums 的所有非空 子序列宽度之和 。由于答案可能非常大,请返回对 109 + 7 取余 后的结果。

子序列 定义为从一个数组里删除一些(或者不删除)元素,但不改变剩下元素的顺序得到的数组。例如,[3,6,2,7] 就是数组 [0,3,1,6,2,2,7] 的一个子序列。

The width of a sequence is the difference between the maximum and minimum elements in the sequence.

Given an array of integers nums, return the sum of the widths of all the non-empty subsequences of nums. Since the answer may be very large, return it modulo 109 + 7.

A subsequence is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, [3,6,2,7] is a subsequence of the array [0,3,1,6,2,2,7].

没想出来,题解feat三叶姐

  • 思路:

    1. 对于某个子序列而言,若其最大值为a,最小值为b,那么该子序列对答案res的贡献是(a-b)

    2. 因此统计每个nums[i]作为最值时,有多少个子序列,统计其对答案的贡献就得到了最终答案

      当nums[i]为最小值时,假设nums中有k个大于nums[i]的数,根据组合数原理,那么子序列个数为 2 k 2^k 2k

      • 其作为最小值是对res的贡献为 2 k ∗ n u m s [ i ] 2^k * nums[i] 2knums[i]

      当nums[i]为最大值时,假设nums中有k个小于nums[i]的数,根据组合数原理,那么子序列个数为 2 k 2^k 2k

      • 其作为最大值是对res的贡献为 2 k ∗ ( − n u m s [ i ] ) 2^k * (-nums[i]) 2k(nums[i])
    3. 如何快速计算比nums[i]大或者小的个数

      • 将nums排序后,大于nums[i]的个数为n-i-1,小于nums[i]的个数为i
    4. nums[i]中的重复元素是否会对结果产生影响?

      • 不会,无论是将 nums[i]视作最大值还是最小值,我们的组合数均取决于某一侧的数的个数,因此不会答案正确性产生影响。
  • 实现:

    • 为了避免重复计算 2 k 2^k 2k,通过打表的方式进行预处理

      class Solution {
          static int MOD = (int)1e9 + 7;
          public int sumSubseqWidths(int[] nums) {        
              long ans = 0;
              int n = nums.length;
              long[] p = new long[n+1];
              p[0] = 1;
              for (int i = 1; i <= n; i++){
                  p[i] = p[i-1] * 2 % MOD;
              }
              Arrays.sort(nums);
              for (int i = 0; i < n; i++){
                  ans += (p[i] * nums[i]) % MOD;
                  ans %= MOD;
                  ans -= (p[n - i - 1] * nums[i]) % MOD;
                  ans %= MOD;
              }
              return (int)ans;
          }
      }
      
    • 复杂度

      • 时间复杂度: O ( n l o g n ) O(n log n) O(nlogn)
      • 空间复杂度: O ( l o g n ) O(logn) O(logn)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值