列表

详情


891. 子序列宽度之和

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

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

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

 

示例 1:

输入:nums = [2,1,3]
输出:6
解释:子序列为 [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3] 。
相应的宽度是 0, 0, 0, 1, 1, 2, 2 。
宽度之和是 6 。

示例 2:

输入:nums = [2]
输出:0

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int sumSubseqWidths(vector<int>& nums) { } };

golang 解法, 执行用时: 212 ms, 内存消耗: 9 MB, 提交时间: 2022-11-18 09:32:17

const mod int = 1e9 + 7

func sumSubseqWidths(nums []int) (ans int) {
    sort.Ints(nums)
    n := len(nums)
    for i, x := range nums {
        ans += (pow(2, i) - pow(2, n-1-i)) * x // 在题目的数据范围下,这不会溢出
    }
    return (ans%mod + mod) % mod // 注意上面有减法,ans 可能为负数
}

func pow(x, n int) int {
    res := 1
    for ; n > 0; n /= 2 {
        if n%2 > 0 {
            res = res * x % mod
        }
        x = x * x % mod
    }
    return res
}

golang 解法, 执行用时: 132 ms, 内存消耗: 8.6 MB, 提交时间: 2022-11-18 09:32:05

func sumSubseqWidths(nums []int) (ans int) {
    const mod int = 1e9 + 7
    sort.Ints(nums)
    n := len(nums)
    pow2 := make([]int, n)
    pow2[0] = 1
    for i := 1; i < n; i++ {
        pow2[i] = pow2[i-1] * 2 % mod // 预处理 2 的幂次
    }
    for i, x := range nums {
        ans += (pow2[i] - pow2[n-1-i]) * x // 在题目的数据范围下,这不会溢出
    }
    return (ans%mod + mod) % mod // 注意上面有减法,ans 可能为负数
}

golang 解法, 执行用时: 124 ms, 内存消耗: 9 MB, 提交时间: 2022-11-18 09:31:45

func sumSubseqWidths(nums []int) (ans int) {
    const mod int = 1e9 + 7
    sort.Ints(nums)
    pow2 := 1
    for i, x := range nums {
        ans += (x - nums[len(nums)-1-i]) * pow2 // 在题目的数据范围下,这不会溢出
        pow2 = pow2 * 2 % mod
    }
    return (ans%mod + mod) % mod // 注意上面有减法,ans 可能为负数
}

python3 解法, 执行用时: 172 ms, 内存消耗: 25 MB, 提交时间: 2022-11-18 09:31:27

'''
x作为排序后数组中索引为i
x作为最小元素的子序列个数为2^i
x作为最大元素的子序列个数为2^(n-1-i)
x对答案的贡献为(2^i - 2^(n-1-i)) * x
'''
class Solution:
    def sumSubseqWidths(self, nums: List[int]) -> int:
        MOD = 10 ** 9 + 7
        nums.sort()
        ans, pow2 = 0, 1
        for x, y in zip(nums, reversed(nums)):
            ans += (x - y) * pow2
            pow2 = pow2 * 2 % MOD
        return ans % MOD

python3 解法, 执行用时: 188 ms, 内存消耗: 25.1 MB, 提交时间: 2022-11-18 09:30:53

'''
x作为排序后数组中索引为i
x作为最小元素的子序列个数为2^i
x作为最大元素的子序列个数为2^(n-1-i)
x对答案的贡献为(2^i - 2^(n-1-i)) * x
'''
class Solution:
    def sumSubseqWidths(self, nums: List[int]) -> int:
        MOD = 10 ** 9 + 7
        MOD2 = (MOD + 1) // 2
        nums.sort()
        ans, pow2, pow2r = 0, 1, pow(2, len(nums) - 1, MOD)
        for x in nums:
            ans += (pow2 - pow2r) * x
            pow2 = pow2 * 2 % MOD
            pow2r = pow2r * MOD2 % MOD
        return ans % MOD

python3 解法, 执行用时: 1164 ms, 内存消耗: 25.2 MB, 提交时间: 2022-11-18 09:30:08

'''
x作为排序后数组中索引为i
x作为最小元素的子序列个数为2^i
x作为最大元素的子序列个数为2^(n-1-i)
x对答案的贡献为(2^i - 2^(n-1-i)) * x
'''
class Solution:
    def sumSubseqWidths(self, nums: List[int]) -> int:
        MOD = 10 ** 9 + 7
        nums.sort()
        return sum((pow(2, i, MOD) - pow(2, len(nums) - 1 - i, MOD)) * x
                   for i, x in enumerate(nums)) % MOD

python3 解法, 执行用时: 256 ms, 内存消耗: 24.6 MB, 提交时间: 2022-11-18 09:29:30

'''
x作为排序后数组中索引为i
x作为最小元素的子序列个数为2^i
x作为最大元素的子序列个数为2^(n-1-i)
x对答案的贡献为(2^i - 2^(n-1-i)) * x
'''
class Solution:
    def sumSubseqWidths(self, nums: List[int]) -> int:
        MOD = 10 ** 9 + 7
        nums.sort()
        n = len(nums)
        pow2 = [0] * n
        pow2[0] = 1
        for i in range(1, n):
            pow2[i] = pow2[i - 1] * 2 % MOD  # 预处理 2 的幂次
        return sum((pow2[i] - pow2[-1 - i]) * x
                   for i, x in enumerate(nums)) % MOD

上一题