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)
相关推荐
Arva .3 小时前
电子书查询列表接口开发
后端
间彧3 小时前
在Spring Cloud Gateway中,如何自定义GlobalFilter实现动态路由规则?
后端
间彧3 小时前
在微服务架构中,过滤器与网关(如Spring Cloud Gateway)如何配合使用?
后端
间彧3 小时前
SpringBoot过滤器详解与项目实战
后端
武子康3 小时前
大数据-121 - Flink 时间语义详解:EventTime、ProcessingTime、IngestionTime 与 Watermark机制全解析
大数据·后端·flink
两万五千个小时3 小时前
LangChain 入门教程:构建你的第一个聊天机器人
后端
间彧4 小时前
SpringBoot如何通过拦截器实现接口限流
后端
间彧4 小时前
Spring Boot拦截器详解与项目实战
后端
绝无仅有4 小时前
面试技巧之Linux相关问题的解答
后端·面试·github