

官解

class Solution(object):# 定义常量mod = int(1e9 + 7) # 模数,用于防止结果溢出inf = float('inf') # 无穷大,用于初始化时的特殊值def sumOfPowers(self, nums, k):n = len(nums) # 数组长度res = 0 # 用于存储最终结果# 三维动态规划表,d[i][p][v] 表示以 nums[i] 结尾的长度为 p 的子序列,最小绝对差为 v 的频次d = [[defaultdict(int) for _ in range(k + 1)] for _ in range(n)]nums.sort() # 对 nums 进行排序,确保子序列的顺序for i in range(n):# 初始化:长度为 1 的子序列,最小绝对差为无穷大,频次为 1d[i][1][self.inf] = 1for j in range(i):# 计算 nums[i] 和 nums[j] 之间的绝对差diff = abs(nums[i] - nums[j])# 更新长度为 p 的子序列的最小绝对差,其中 p 从 2 到 kfor p in range(2, k + 1):for v, cnt in d[j][p - 1].items():# 更新 d[i][p][min(diff, v)]d[i][p][min(diff, v)] = (d[i][p][min(diff, v)] + cnt) % self.mod# 计算结果:遍历所有以 nums[i] 结尾的长度为 k 的子序列for v, cnt in d[i][k].items():# 累加 v * cnt 到 res 中,并取模res = (res + v * cnt % self.mod) % self.modreturn res # 返回最终结果
Chatgpt解
这段代码实现了一个名为sumOfPowers的方法,它的目标是计算给定数组 nums 中所有长度为 k 的子序列的最小绝对差的和,并将结果对 1e9 + 7 取模。
代码分解与解释
变量和数据结构
mod = int(1e9 + 7): 模数,用于防止结果溢出。inf = float('inf'): 表示无穷大,用于初始化时的特殊值。d = [[defaultdict(int) for _ in range(k + 1)] for _ in range(n)]: 三维动态规划表,用于存储子序列的最小绝对差。d[i][p]表示以nums[i]结尾的长度为p的子序列,其最小绝对差的频次。d[i][p][v]表示上述子序列中,最小绝对差为v的子序列数量。
算法步骤
-
初始化:
n = len(nums): 数组nums的长度。res = 0: 用于存储最终结果。nums.sort(): 对nums进行排序,确保子序列的顺序。- 初始化
d[i][1][inf] = 1,表示长度为 1 的子序列,最小绝对差为无穷大。
-
动态规划填表:
- 遍历数组的每一个元素
nums[i]:- 对于每一个之前的元素
nums[j](其中j < i):- 计算
nums[i]和nums[j]之间的绝对差diff。 - 更新长度为
p的子序列的最小绝对差,其中p从 2 到k:- 对于
d[j][p-1]中的每个v和cnt:- 更新
d[i][p][min(diff, v)],其中v是子序列的最小绝对差,cnt是其出现的频次。 - 使用
min(diff, v)确保当前子序列的最小绝对差。
- 更新
- 对于
- 计算
- 对于每一个之前的元素
- 遍历数组的每一个元素
-
计算结果:
- 遍历所有以
nums[i]结尾的长度为k的子序列:- 对于每个最小绝对差
v和其出现的频次cnt:- 累加
v * cnt到res中,并取模。
- 累加
- 对于每个最小绝对差
- 遍历所有以
返回结果
- 返回
res,即所有长度为k的子序列的最小绝对差的和,并对1e9 + 7取模。
代码的关键点
- 使用三维动态规划表
d来存储子序列信息。 - 确保子序列按照递增顺序进行计算,避免重复计算。
- 通过
min(diff, v)保持子序列的最小绝对差。
总结
这段代码通过动态规划的方法有效地计算了所有长度为 k 的子序列的最小绝对差,并利用模数 1e9 + 7 处理可能出现的大数溢出问题。代码的核心思想是利用前缀子序列的信息来逐步构建长度为 k 的子序列,并在构建过程中不断更新最小绝对差。