华为OD机考2025B卷 - 最小循环子数组(Java & Python& JS & C++ & C )

最新华为OD机试

真题目录:点击查看目录
华为OD面试真题精选:点击立即查看

题目描述

给定一个由若干整数组成的数组nums,请检查数组是否是由某个子数组重复循环拼接而成,请输出这个最小的子数组。

输入描述

第一行输入数组中元素个数n,1 ≤ n ≤ 100000

第二行输入数组的数字序列nums,以空格分割,0 ≤ nums[i] < 10

备注

数组本身是其最大的子数组,循环1次可生成的自身;

输出描述

输出最小的子数组的数字序列,以空格分割;

示例1

输入

9
1 2 1 1 2 1 1 2 1

输出

1 2 1

说明

数组[1,2,1,1,2,1,1,2,1] 可由子数组[1,2,1]重复循环3次拼接而成

解题思路

问题理解

这道题要求我们找到一个最小的子数组,该子数组通过循环拼接可以构成原始数组。例如,对于数组 [1,2,1,1,2,1,1,2,1],最小的循环子数组是 [1,2,1],它重复3次可以生成原数组。

算法原理

这个问题可以使用 KMP 算法的思想来解决。KMP 算法主要用于字符串匹配,但其中的"前缀函数"(next数组)可以帮助我们找到循环模式。

KMP 的 next 数组在这里的应用

  1. next数组记录了每个位置的最长相等前后缀长度
  2. 对于数组末尾位置 i,next[i] 表示数组的前 next[i] 个元素与末尾的 next[i] 个元素相同
  3. 如果数组是由某个子数组循环构成的,那么 (数组长度 - next[末尾位置]) 就是可能的循环子数组的长度

关键思路

如果一个数组是循环构成的,假设循环子数组长度为 k,数组长度为 n,则有:

  • n 必须是 k 的整数倍
  • 如果 (n % (n - next[n-1]) == 0),说明数组可以被分成整数个循环子数组
  • 此时最小循环子数组长度为 (n - next[n-1])
  • 否则,无法找到真正的循环子数组,整个数组本身就是最小的"循环子数组"(循环1次)

示例分析

对于输入 [1,2,1,1,2,1,1,2,1]

  1. 构建 next 数组:[0,0,1,1,2,3,4,5,6]
  2. 最后一个元素的 next 值是 6
  3. 计算:9 % (9 - 6) = 9 % 3 = 0,可以整除
  4. 因此最小循环子数组长度为 3
  5. 输出前 3 个元素:[1,2,1]

Java

import java
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值