华为OD 最小循环子数组

1. 题意

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

2. 题解

利用 k m p kmp kmp中的 n e x t next next数组性质,我们可以求出 n u m s nums nums中的最长公共

前缀后缀。如果要是由一个子数组循环组成的话,那么必然有 n e x t [ s z ] % ( n − n e x t [ s z ] ) = 0 next[sz] \% (n-next[sz]) =0 next[sz]%(n−next[sz])=0。

为什么满足这个性质就能说明是由子数组循环若干次组成的呢?

我们假设上面的条件成立,且将字符串每 k = n − n e x t [ n ] k = n-next[n] k=n−next[n]个划为一组。那么字符串可以表示为 b 1 ⋯ b n / k b_1\cdots\ b_{n/k} b1⋯ bn/k。

由于 k = n − n e x t [ n ] k=n-next[n] k=n−next[n], 因此串 b 0 b 1 ⋯ b n / k − 1 = b 2 ⋯ b n / k b_0b_1\cdots b_{n/k-1}=b_2\cdots b_{n/k} b0b1⋯bn/k−1=b2⋯bn/k(最长公共前后缀)。进而
b 1 = b 2 b 2 = b 3 ⋯ b n / k − 1 = b n / k b_1=b_2\\ b_2=b_3\\ \cdots\\ b_{n/k-1}=b_{n/k} b1=b2b2=b3⋯bn/k−1=bn/k

因此
b 1 = b 2 = ⋯ = b n / k b_1=b_2=\cdots=b_{n/k} b1=b2=⋯=bn/k

串为循环串。

例如

复制代码
s     :    a  b c a b c a b c
next  :    -1 0 0 0 1 2 3 4 5 6
n = 9
next[n] = 6
n -next[n] = 3
6 = 2 x 3
  • 代码
cpp 复制代码
#include <iostream>
#include <string>
#include <vector>

int main()
{
    int n;
    std::cin >> n;

    std::vector<int> a(n, 0);

    for ( int i = 0; i < n; ++i) {
        std::cin >> a[i];
    }

    std::vector<int> next( n + 1, 0);
    int j = -1;
    int i =  0;
    next[0] = -1;

    while ( i < n) {
        if ( j == -1 || a[i] == a[j]) {
            ++i;
            ++j;
            next[i] = j;
        }
        else {
            j = next[j];
        }
    }

    int k = n;
    if ( (next[n] >= (n - next[n])) && (next[n] % (n - next[n]) == 0)) {
        k = n - next[n];
    }

    for (int i = 0; i < k; ++i) {
        if ( i )
            std::cout << " ";
        std::cout << a[i];
    }


    return 0;
}
相关推荐
空山新雨后、4 分钟前
从 CIFAR 到 ImageNet:计算机视觉基准背后的方法论
人工智能·深度学习·算法·计算机视觉
YuTaoShao13 分钟前
【LeetCode 每日一题】712. 两个字符串的最小ASCII删除和——(解法三)状态压缩
算法·leetcode·职场和发展
liliangcsdn16 分钟前
LLM训练中batchsize与过拟合和泛化的关系
人工智能·算法·机器学习
muddjsv20 分钟前
什么是算法?——现代视角下的一次凝视
算法
laplace012321 分钟前
智能体经典范式构建
算法·langchain·大模型·agent
小雨下雨的雨22 分钟前
Flutter鸿蒙共赢——色彩的流变:流体梯度网格与现代视觉重构
算法·flutter·华为·重构·交互·harmonyos·鸿蒙
Swift社区23 分钟前
LeetCode 473 火柴拼正方形 - Swift 题解
算法·leetcode·swift
Allen_LVyingbo23 分钟前
面向“病历生成 + CDI/ICD”多智能体系统的选型策略与落地实践(三)
算法·自然语言处理·性能优化·知识图谱·健康医疗·柔性数组
金枪不摆鳍25 分钟前
算法-链表双指针
数据结构·算法·链表
MarkHD26 分钟前
智能体在车联网中的应用:第53天 基于CTDE-MAPPO的快速路合流区协同驾驶项目蓝图(SUMO路网与智能体设计篇)
算法