2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k,

定义一个子序列的能量为子序列中任意两个元素之间的差值绝对值的最小值。

找出nums中长度为k的所有子序列的能量和,

对结果取模10^9 + 7后返回。

输入:nums = [1,2,3,4], k = 3。

输出:4。

解释:

nums 中总共有 4 个长度为 3 的子序列:[1,2,3] ,[1,3,4] ,[1,2,4] 和 [2,3,4] 。能量和为 |2 - 3| + |3 - 4| + |2 - 1| + |3 - 4| = 4 。

答案2024-11-13:

chatgpt

题目来自leetcode3098。

大体步骤如下:

1.输入解析:

  • 输入一个整数数组 nums 和一个正整数 k。

  • 例如:nums = [1, 2, 3, 4],k = 3。

2.预处理:

  • 对 nums 进行排序,以便更容易处理差值。

  • 计算所有可能的差值 vals,即对于每一对 (nums[i], nums[j])(i > j),计算 nums[i] - nums[j],并将这些差值存入 vals。

  • 将一个无穷大值 inf 添加到 vals 中,确保后续处理边界情况。

  • 对 vals 进行排序并去重,得到唯一的差值数组。

3.动态规划数组初始化:

  • 初始化三维数组 d,其中 d[i][p][v] 表示考虑到第 i 个元素,长度为 p 的子序列中,最小差值为 vals[v] 的子序列个数。

  • 初始化二维数组 border,其中 border[i][p] 表示考虑到第 i 个元素,长度为 p 的子序列中,当前处理到的 vals 数组的索引边界。

  • 初始化二维数组 sum 和 suf,用于计算前缀和和后缀和,以便快速更新 d 数组。

4.动态规划填充:

  • 遍历 nums 中的每个元素 nums[i],并对于每个 j < i,计算 nums[i] - nums[j] 在 vals 中的位置 pos。

  • 对于每个可能的子序列长度 p(从 1 到 k),更新 d, sum, suf, 和 border 数组。

  • 这一步的核心是利用前缀和和后缀和快速更新 d 数组,以及利用 border 数组来避免重复计算。

5.结果计算:

  • 遍历每个 d[i][k][v],其中 i 是 nums 的索引,k 是子序列长度,v 是 vals 的索引。

  • 计算每个 d[i][k][v] 对结果的贡献,即 vals[v] * d[i][k][v],并累加到 res 中。

  • 对 res 取模 10^9 + 7 后返回。

6.输出:

  • 输出最终计算得到的 res。

时间复杂度:

  • 排序 nums:O(n log n)

  • 生成 vals 并排序去重:O(n^2 log n^2)(因为最多有 n(n-1)/2 个差值,但去重和排序的复杂度较高)

  • 动态规划填充:O(n^2 k m),其中 n 是 nums 的长度,k 是子序列长度,m 是 vals 的长度(去重后的差值个数)。

  • 结果计算:O(n m)

  • 总时间复杂度:由于 m 最多为 n^2,因此总时间复杂度为 O(n^4 k),但在实际情况下,由于 vals 的去重,m 通常远小于 n^2。

空间复杂度:

  • 三维数组 d:O(n k m)

  • 二维数组 border, sum, suf:O(n k) 和 O(k m)

  • 其他辅助数组和变量:O(n^2)(用于存储差值 vals)

  • 总空间复杂度:O(n k m + n^2),同样地,由于 m 通常远小于 n^2,实际空间使用会更少。

综上所述,尽管理论上的时间复杂度和空间复杂度较高,但由于 vals 的去重和排序效率,以及动态规划过程中的前缀和、后缀和优化,实际运行时的性能可能会更好。

Go完整代码如下:

package main

import (
"fmt"
"sort"
) const mod = 1e9 + 7
const inf = 0x3f3f3f3f func sumOfPowers(nums []int, k int) int {
n := len(nums)
sort.Ints(nums) var vals []int
for i := 0; i < n; i++ {
for j := 0; j < i; j++ {
vals = append(vals, nums[i]-nums[j])
}
}
vals = append(vals, inf)
sort.Ints(vals)
vals = unique(vals) d := make([][][]int, n)
for i := range d {
d[i] = make([][]int, k+1)
for j := range d[i] {
d[i][j] = make([]int, len(vals))
}
} border := make([][]int, n)
for i := range border {
border[i] = make([]int, k+1)
} sum := make([][]int, k+1)
for i := range sum {
sum[i] = make([]int, len(vals))
} suf := make([][]int, n)
for i := range suf {
suf[i] = make([]int, k+1)
}
for i := 0; i < n; i++ {
for j := 0; j < i; j++ {
pos := sort.SearchInts(vals, nums[i]-nums[j])
for p := 1; p <= k; p++ {
for border[j][p] < pos {
sum[p][border[j][p]] = (sum[p][border[j][p]] - suf[j][p] + mod) % mod
sum[p][border[j][p]] = (sum[p][border[j][p]] + d[j][p][border[j][p]]) % mod
suf[j][p] = (suf[j][p] - d[j][p][border[j][p]] + mod) % mod
border[j][p]++
sum[p][border[j][p]] = (sum[p][border[j][p]] + suf[j][p]) % mod
}
}
} d[i][1][len(vals)-1] = 1
for p := 2; p <= k; p++ {
for v := 0; v < len(vals); v++ {
d[i][p][v] = sum[p-1][v]
}
}
for p := 1; p <= k; p++ {
for v := 0; v < len(vals); v++ {
suf[i][p] = (suf[i][p] + d[i][p][v]) % mod
}
sum[p][0] = (sum[p][0] + suf[i][p]) % mod
}
} res := 0
for i := 0; i < n; i++ {
for v := 0; v < len(vals); v++ {
res = (res + int(int64(vals[v])*int64(d[i][k][v])%mod)) % mod
}
}
return res
} func unique(arr []int) []int {
if len(arr) == 0 {
return arr
}
result := []int{arr[0]}
for _, v := range arr {
if v != result[len(result)-1] {
result = append(result, v)
}
}
return result
} func main() {
nums := []int{1, 2, 3, 4}
k := 3
fmt.Println(sumOfPowers(nums, k))
}

Rust完整代码如下:

use std::collections::HashSet;

const MOD: i32 = 1_000_000_007;
const INF: i32 = 0x3f3f3f3f; fn sum_of_powers(nums: Vec<i32>, k: usize) -> i32 {
let n = nums.len();
let mut nums = nums;
nums.sort(); let mut vals = Vec::new();
for i in 0..n {
for j in 0..i {
vals.push(nums[i] - nums[j]);
}
}
vals.push(INF);
vals.sort();
vals = unique(vals); let mut d = vec![vec![vec![0; vals.len()]; k + 1]; n]; let mut border = vec![vec![0; k + 1]; n];
let mut sum = vec![vec![0; vals.len()]; k + 1];
let mut suf = vec![vec![0; k + 1]; n]; for i in 0..n {
for j in 0..i {
let pos = match vals.binary_search(&(nums[i] - nums[j])) {
Ok(p) => p,
Err(p) => p,
};
for p in 1..=k {
while border[j][p] < pos {
sum[p][border[j][p]] =
(sum[p][border[j][p]] - suf[j][p] + MOD) % MOD;
sum[p][border[j][p]] =
(sum[p][border[j][p]] + d[j][p][border[j][p]]) % MOD;
suf[j][p] = (suf[j][p] - d[j][p][border[j][p]] + MOD) % MOD;
border[j][p] += 1;
sum[p][border[j][p]] =
(sum[p][border[j][p]] + suf[j][p]) % MOD;
}
}
} d[i][1][vals.len() - 1] = 1;
for p in 2..=k {
for v in 0..vals.len() {
d[i][p][v] = sum[p - 1][v];
}
}
for p in 1..=k {
for v in 0..vals.len() {
suf[i][p] = (suf[i][p] + d[i][p][v]) % MOD;
}
sum[p][0] = (sum[p][0] + suf[i][p]) % MOD;
}
} let mut res = 0;
for i in 0..n {
for v in 0..vals.len() {
res = (res + vals[v] as i64 * d[i][k][v] as i64 % MOD as i64) % MOD as i64;
}
}
res as i32
} fn unique(mut arr: Vec<i32>) -> Vec<i32> {
if arr.is_empty() {
return arr;
}
arr.sort();
let mut result = Vec::new();
let mut prev = arr[0];
result.push(prev);
for &v in &arr[1..] {
if v != prev {
result.push(v);
prev = v;
}
}
result
} fn main() {
let nums = vec![1, 2, 3, 4];
let k = 3;
println!("{}", sum_of_powers(nums, k));
}

2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k, 定义一个子序列的能量为子序列中任意两个元素之间的差值绝对值的最小值。 找出nums中长度为k的所有子的更多相关文章

  1. JAVA中计算两个日期时间的差值竟然也有这么多门道

    上半年春招的时候,作为面试官,对于面试表现的不错的同学会要求其写一小段代码看看.题目很简单: 给定一个日期,然后计算下距离今天相差的天数. 本以为这么个问题就是用来活跃面试氛围的,但是结果却让人大跌眼 ...

  2. 在excel中如何计算两个时间之间的差[转]

    因为时间是由序列号所代表的,用户可以用较晚的时间减去较早的时间以得到间隔.例如,单元格A3含有5:30,单元格B3含有14:00,下面的公式返回8:30(间隔8小时30分). =B3-A3 然而,如果 ...

  3. [Xcode 实际操作]九、实用进阶-(4)计算两个日期间的差值

    目录:[Swift]Xcode实际操作 本文将演示如何计算两个日期之间的差值. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class ...

  4. 用Scala实现集合中相邻元素间的差值

    欢迎转载,转载请注明出处,徽沪一郎. 概要 代码这东西,不写肯定不行,新学Scala不久,将实际遇到的一些问题记录下来,日后也好查找. 今天讲的是如何计算同一集合中元素两两之间的差值,即求开始集合(a ...

  5. 给定一个数组,求如果排序后,相邻两个元素的最大差值,要求时间复杂度为O(N)

    第一种方法: 计数排序后,然后找出两两之间的最大差值 计数排序的时间复杂度是O(N) public class CountSort { public static void main(String[] ...

  6. Jquery计算时间戳之间的差值,可返回年,月,日,小时等

    /** * 计算时间戳之间的差值 * @param startTime 开始时间戳 * @param endTime 结束时间戳 * @param type 返回指定类型差值(year, month, ...

  7. 218。重复元素II(重复元素的下标差值<=K)(哈希)

    给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k. 示例 1: 输入: nums ...

  8. js计算两个日期的天数差值

    js计算两个日期的天数差值 通过两个日期计算这两个日期之间的天数差值 /** * 计算天数差的函数,通用 * @param sDate1 * @param sDate2 * @returns {Num ...

  9. [转]ASP.NET MVC中的两个Action之间值的传递--TempData

    本文转自:ASP.NET MVC中的两个Action之间值的传递--TempData 一. ASP.NET MVC中的TempData 在ASP.NET MVC框架的ControllerBase中存在 ...

  10. 【编程题目】一个整数数组,长度为 n,将其分为 m 份,使各份的和相等,求 m 的最大值★★ (自己没有做出来!!)

    45.雅虎(运算.矩阵): 2.一个整数数组,长度为 n,将其分为 m 份,使各份的和相等,求 m 的最大值 比如{3,2,4,3,6} 可以分成 {3,2,4,3,6} m=1; {3,6}{2,4 ...

随机推荐

  1. Python自动复制Excel数据:将各行分别重复指定次数

      本文介绍基于Python语言,读取Excel表格文件数据,并将其中符合我们特定要求的那一行加以复制指定的次数,而不符合要求的那一行则不复制:并将所得结果保存为新的Excel表格文件的方法.   这 ...

  2. JVM笔记二双亲委派机制

    JVM笔记二双亲委派机制 JVM双亲委派机制,简单来说:我爸是李刚,有事找我爸.用三个字来说:往上捅.不信?咱们一起看看. ​ JVM的双亲委派机制 JVM类加载器是什么机制?为什么使用这种机制(这种 ...

  3. C++ : 仅添加一个引用& 就直接导致程序崩溃

    问题描述 在项目某次开发中,测试过程中出现了coredump问题.经过asan工具检测,报了heap-use-after-free内存错误,最终定位到竟是无意中添加了一个引用&导致的! 开发时 ...

  4. C++ shared_ptr是线程安全的吗?

    导读:C++面试中有时会有这样一个问题,shared_ptr是线程安全的吗?对此问题,我们需要从三个并发场景进行考虑,拷贝shared_ptr的安全性.对shared_ptr赋值的安全性和读写shar ...

  5. 一文看懂global, nonlocal, local变量

    Python中,变量是根据程序运行顺序进行的,比如函数外的变量,在函数内是可见的,但是可用,不可赋值.那么如何实现赋值呢? 利用global关键字进行. 在函数内,如果出现和函数外的变量同名变量,而且 ...

  6. 音视频FAQ(三):音画不同步

    摘要 本文介绍了音画不同步问题的五个因素:编码和封装阶段.网络传输阶段.播放器中的处理阶段.源内容产生的问题以及转码和编辑.针对这些因素,提出了相应的解决方案,如使用标准化工具.选择强大的传输协议.自 ...

  7. Shiro-认证绕过漏洞(CVE-2020-1957)

    漏洞原理 核心点就是shiro和spring对uri进行配合匹配的时候有缺陷导致的,shiro中很轻易就能绕过,其次spring中对;分号好像情有独钟,被大牛们发现后也就一下子绕过了. 主流paylo ...

  8. 【赵渝强老师】删除表和Oracle的回收站

    一.Oracle的Drop Table语句 首先,我们来看一下Oracle Drop Table的语法格式. 解释一下里面的参数: schema Schema表示方案名称,这里可以理解为用户名,缺省为 ...

  9. linux java 初始环境配置

    linux初始环境配置 1.设置IP 查看虚拟机ip地址:ip addr 修改ip地址 Vi /etc/sysconfig/network~scrips/ifcfg-ens33(不一定是33 动态的) ...

  10. Makefile优化编译速度

    并行编译:使用 make -j 命令来进行并行编译,可以加快编译速度.-j 后面可以跟一个数字,表示并行编译的线程数. 懒惰计算:使用 .PHONY 规则来避免无谓的重新编译.该规则告诉 make,这 ...