华为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.u

你可能感兴趣的:(最新华为OD机试真题,华为OD机试真题,(Java/JS/Py/C),java,华为od,python,javascript,c++,华为OD机考2025B卷)