2025-10-11:求出数组的 X 值Ⅰ。用go语言,给定一个只包含正整数的数组 nums 和一个正整数 k。 你可以进行一次删除操作:在数组两端各自选取一段

2025-10-11:求出数组的 X 值Ⅰ。用go语言,给定一个只包含正整数的数组 nums 和一个正整数 k。

你可以进行一次删除操作:在数组两端各自选取一段连续元素删掉(这两段不能相互重叠),删除后数组必须至少保留一个元素。两端要删的那段可以为空(即可以只删左端、只删右端或都不删),但不能删掉整个数组。

对每一种合法的删除方式,计算剩下的那段元素的乘积对 k 取模后的值 x。定义 nums 的 x 值为能得到该模值 x 的删除方式数量。

请输出一个长度为 k 的数组 result,其中 result[x](0 ≤ x ≤ k−1)表示得到模值 x 的删除方式数。

1 <= nums[i] <= 1000000000。

1 <= nums.length <= 100000。

1 <= k <= 5。

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

输出: [9,6]。

题目来自力扣3524。

算法过程分步描述

1. 初始化阶段

  • 创建一个长度为 k 的结果数组 ans,初始化为全0,用于存储每个模值 x 对应的删除方式数量
  • 创建一个长度为 k 的状态数组 f,初始化为全0,用于动态记录当前所有可能乘积模 k 的路径数量

2. 遍历数组处理每个元素

对于数组 nums 中的每个元素 v

2.1 创建新的状态数组

  • 创建一个新的状态数组 nf,长度为 k,初始化为全0

2.2 处理当前元素单独形成子数组的情况

  • 计算当前元素 vk 取模的值:v % k
  • nf 中对应的位置计数加1,表示当前元素单独作为一个子数组的情况

2.3 基于之前的状态更新新状态

  • 遍历之前状态数组 f 中的所有模值 y 及其对应的计数 c
  • 对于每个 (y, c) 对,计算新的模值:(y * v) % k
  • 将之前的计数 c 累加到新状态 nf 中对应的模值位置上
  • 这表示将当前元素 v 与之前所有可能的子数组乘积进行组合

2.4 更新状态和结果

  • 将旧状态 f 更新为新状态 nf
  • 将新状态 nf 中的所有计数累加到结果数组 ans 的对应位置上

3. 算法逻辑解释

  • 该算法实际上是在动态统计所有可能的连续子数组(通过删除两端得到)的乘积模 k 值的分布
  • 每次处理新元素时,考虑:
    • 该元素单独作为一个子数组
    • 该元素与之前所有子数组组合形成新的子数组
  • 状态数组 f 记录了到当前位置为止,所有可能子数组乘积模 k 值的分布情况

4. 示例分析(nums = [1,1,2,1,1], k = 2)

  • 最终得到结果:[9,6]
  • 表示模值为0的删除方式有9种,模值为1的删除方式有6种
  • 这与题目描述的输出一致

复杂度分析

总的时间复杂度:O(n × k)

  • 需要遍历数组中的 n 个元素
  • 对于每个元素,需要遍历长度为 k 的状态数组
  • 由于 k ≤ 5,实际可以视为 O(n)

总的额外空间复杂度:O(k)

  • 只需要维护两个长度为 k 的状态数组(f 和 nf)
  • 结果数组 ans 的长度也为 k
  • 空间使用与输入数组大小 n 无关

Go完整代码如下:

go 复制代码
package main

import (
	"fmt"
)

func resultArray(nums []int, k int) []int64 {
	ans := make([]int64, k)
	f := make([]int, k)
	for _, v := range nums {
		nf := make([]int, k)
		nf[v%k] = 1
		for y, c := range f {
			nf[y*v%k] += c
		}
		f = nf
		for x, c := range f {
			ans[x] += int64(c)
		}
	}
	return ans
}

func main() {
	nums := []int{1, 1, 2, 1, 1}
	k := 2
	result := resultArray(nums, k)
	fmt.Println(result)
}

Python完整代码如下:

python 复制代码
# -*-coding:utf-8-*-

def result_array(nums, k):
    ans = [0] * k
    f = [0] * k
    for v in nums:
        nf = [0] * k
        nf[v % k] = 1
        for y, c in enumerate(f):
            nf[(y * v) % k] += c
        f = nf
        for x, c in enumerate(f):
            ans[x] += c
    return ans

if __name__ == "__main__":
    nums = [1, 1, 2, 1, 1]
    k = 2
    result = result_array(nums, k)
    print(result)
相关推荐
Cache技术分享2 分钟前
415. Java 文件操作基础 - 精准读取压缩诗集:从二进制文件中高效提取指定十四行诗
前端·后端
XovH7 分钟前
Django 从 0 到 1 打造完整电商平台:收货地址管理
后端
Postkarte不想说话25 分钟前
Jupyter Lab安装
后端
fliter27 分钟前
在 Async Rust 中实现请求合并(Request Coalescing)
后端
王立志_LEO28 分钟前
Gunicorn 启动django服务
后端
fliter29 分钟前
一个让我调试一周的 Rust match 陷阱
后端
一只大袋鼠40 分钟前
SpringBoot 初学阶段知识点汇总(一)
spring boot·笔记·后端
Rust研习社42 分钟前
Rust 官方拟定 LLM 政策,防止 LLM 污染开源社区?
开发语言·后端·ai·rust·开源
无风听海1 小时前
ASP.NET Core Minimal API 深度解析
后端·asp.net