首页 > 其他分享 >2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k, 定义一个子序列的能量为子序列中任意两个元素之间的差值绝对值的最小值。 找出nums中长度为k的所有子

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

时间:2024-11-13 15:31:13浏览次数:1  
标签:suf nums sum vals let 序列 能量 border

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 数组的索引边界。

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

4.动态规划填充

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

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

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

5.结果计算

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

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

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

6.输出

  • 输出最终计算得到的 res

时间复杂度

  • 排序 numsO(n log n)

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

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

  • 结果计算:O(n m)

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

空间复杂度

  • 三维数组 dO(n k m)

  • 二维数组 border, sum, sufO(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));
}

在这里插入图片描述

标签:suf,nums,sum,vals,let,序列,能量,border
From: https://www.cnblogs.com/moonfdd/p/18544066

相关文章

  • 力扣21 打卡15 长度为 K 的子数组的能量值 II
    思路:该算法使用滑动窗口和计数器来判断每个长度为(k)的子数组是否满足连续递增的条件。遍历数组时,使用cnt记录当前连续递增的元素数。如果当前元素和前一个元素不连续递增,则将cnt重置为1,否则增加cnt。当cnt大于等于(k)时,表示找到了一个满足条件的子数组,将......
  • 数据库序列器
    在数据库管理系统中,序列(Sequence)是一种数据库对象,主要用于生成唯一的数值。不同的数据库系统对序列的支持方式可能不同。下面是DB2和MySQL中关于序列的一些信息: ###DB2中的序列 在IBM的DB2数据库中,序列是一个独立的对象,可以被多个表或应用程序共享。通过使用`CREATESEQ......
  • 夏光明:数字能量风水、算命、看八字骗局大揭秘
    在现代社会,一些所谓的“大师”利用人们对未知的恐惧和对命运的好奇,通过互联网平台大肆宣传数字能量风水,算命、看八字,声称能够通过手机号码、生辰八字等预测个人命运并提供改运服务。然而,这些看似神秘的服务背后隐藏着精心策划的骗局。数字能量风水的虚假宣传所谓的“数字能......
  • 夏光明:手机号能改变命运?警惕“算命大师”的数字能量学诈骗
    在现代社会,当人们面临挑战和不顺时,有时会寻求“大师”的指引以求心灵的慰藉。然而,这种寻求帮助的行为有时会被不法分子所利用,成为诈骗的温床。2021年4月,郑州市的小韩就陷入了这样一个精心设计的诈骗陷阱。小韩在工作和生活中感到不顺,通过抖音了解到一个可以通过生辰八字测算数......
  • LEAN 之 Cauchy 序列(Cauchy Sequence)
    直观感受(Intuition)         Cauchy序列(CauchySequence)是指,当一个序列 (x₀,x₁,...)在它一直往后延伸时,它的元素越靠越近,那么,该序列是 Cauchy序列(CauchySequence)。        Cauchy序列(CauchySequence)有可能最终收敛(Converges)于一个值,也有可能一直......
  • 序列化和反序列化
    目录一、是什么序列化(Serialization)反序列化(Deserialization)二、使用场景三、框架四、问题五、Jackson枚举反序列化器一、是什么序列化(Serialization)是将数据结构或对象转换成一种可存储或可传输格式的过程。在序列化后,数据可以被写入文件、发送到网络或存储在数......
  • 代码随想录算法训练营day43| 300.最长递增子序列 674. 最长连续递增序列 718. 最长
    学习资料:https://programmercarl.com/0300.最长上升子序列.html#算法公开课动态规划系列之子序列学习记录300.最长递增子序列(长度最少为1;dp[i]代表到i为止的最长子序列的长度;i的值根据i之前比如j的值来判断;每个地方都有可能获得最长长度)点击查看代码classSolution:def......
  • 改进图卷积+informer时间序列预测代码
    本代码尝试将它转移用到时间序列中,创新思维的三维转二维,利用部分卷积进行特征提取,将提取的结果放入informer或者tranformer进行预测,预测还不错(适用的领域效果比二维差一点,但是这个思路用的人几乎没有人用!创新点很强)同时证实了引入图卷积的可行性。1.informerInformer是一种......
  • 7-35 求给定精度的简单交错序列部分和
    本题要求编写程序,计算序列部分和1-1/4+1/7-1/10+...直到最后一项的绝对值不大于给定精度eps。输入格式:输入在一行中给出一个正实数eps。输出格式:在一行中按照“sum=S”的格式输出部分和的值S,精确到小数点后六位。题目保证计算结果不超过双精度范围。输入样......
  • (代码随想录)leetcode300. 最长递增子序列
    自己还是写不出来[笑哭]思路错了,自己死要去只遍历一遍代码随想录答案:classSolution{public:intlengthOfLIS(vector<int>&nums){if(nums.size()<=1)returnnums.size();vector<int>dp(nums.size(),1);//所有元素都是1长度//dp[i]......