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)
相关推荐
东东516几秒前
OA自动化居家办公管理系统 ssm+vue
java·前端·vue.js·后端·毕业设计·毕设
程序员鱼皮15 分钟前
前特斯拉 AI 总监:AI 编程最大的谎言,是 “提效”
前端·后端·ai·程序员·开发
好好研究1 小时前
SpringBoot使用外置Tomcat
spring boot·后端·tomcat
索荣荣1 小时前
Spring Boot 实现DOCX转PDF(基于docx4j的轻量级开源方案)
spring boot·后端·pdf
mit6.8241 小时前
[todo]10个常见的后端框架
后端
没有bug.的程序员1 小时前
Spring Boot 与 Sleuth:分布式链路追踪的集成、原理与线上故障排查实战
java·spring boot·分布式·后端·分布式链路追踪·sleuth·线上故障排查
爱敲代码的憨仔2 小时前
Spring-AOP
java·后端·spring
短剑重铸之日2 小时前
《设计模式》第四篇:观察者模式
java·后端·观察者模式·设计模式
Hx_Ma162 小时前
SpringBoot注册格式化器
java·spring boot·后端
乔江seven2 小时前
【python轻量级Web框架 Flask 】1 Flask 初识
开发语言·后端·python·flask