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

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

时间:2024-11-13 21:50:19浏览次数:3  
标签:suf nums int sum vals 序列 能量 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,int,sum,vals,序列,能量,border
From: https://blog.csdn.net/weixin_48502062/article/details/143743320

相关文章

  • 代码审计:TP5 框架及无框架变量覆盖与反序列化
    目录代码审计:TP5框架及无框架变量覆盖与反序列化一、什么是TP5框架及无框架变量覆盖与反序列化审计二、原理(一)变量覆盖原理(二)变量覆盖与文件包含漏洞结合原理(三)反序列化原理(文中虽未详细提及,但为完整理解可补充)三、步骤与代码示例(一)准备工作(二)审计步骤与代码分析......
  • P2779 [AHOI2016初中组] 黑白序列题解
    题意:小可可准备了一个未完成的黑白序列,用B和W表示黑色和白色,用?表示尚未确定。他希望知道一共有多少种不同的方法,在决定了每一个?位置的颜色后可以得到一个小雪喜欢的黑白序列。其中,小雪喜欢的黑白序列指的是对于任何正整数\(n\),由连续\(n\)个黑接上连续\(n\)个白......
  • 代码随想录算法训练营第二十五天| leetcode491.递增子序列、leetcode46.全排列、leetc
    1leetcode491.递增子序列题目链接:491.非递减子序列-力扣(LeetCode)文章链接:代码随想录视频链接:回溯算法精讲,树层去重与树枝去重|LeetCode:491.递增子序列_哔哩哔哩_bilibili思路:用之前的方法,结果翻车了,好好看视频学新技能吧1.1视频后的思路真的没想到用set来去重,还是基......
  • 2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k, 定义
    2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k,定义一个子序列的能量为子序列中任意两个元素之间的差值绝对值的最小值。找出nums中长度为k的所有子序列的能量和,对结果取模10^9+7后返回。输入:nums=[1,2,3,4],k=3。输出:4。解释:nums......
  • 力扣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)是将数据结构或对象转换成一种可存储或可传输格式的过程。在序列化后,数据可以被写入文件、发送到网络或存储在数......