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
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 105
原站题解
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