【题解】LC:Z 算法(Z Algorithm)

教练开了一个新的企划。

官网:Library Checker

做 Library Checker。前面忘了后面忘了猫娘要极速做完。


一眼恶心kmp。 例题和题解详见:【字符串算法集合】KMP & EXKMP & Manacher & Trie 树 & AC 自动机-CSDN博客

本题题解注释代码:

cpp 复制代码
#include<bits/stdc++.h> 
using namespace std;
 
typedef long long LL;
const int N = 5e5 + 10; 
char s[N];    
LL z[N];          // z: s 的 Z 函数数组
int len;
 
// 计算文本串 s 的 Z 函数
// z[i] 表示 s[i..lenb]与 s[1..lenb] 的最长公共前缀长度(LCP) 
void get_z() {
	memset(z, 0, sizeof(z)); 
    z[1] = len;  // 特殊情况:s[1..lenb]与自身的 LCP 就是整个字符串长度
    
    // 初始化最右匹配区间 [l, r]
    // 这区间就是 s[l..r] = s[1..r - l + 1]
    // l、r: 当前已知最右匹配区间的左端点和右端点
    for (int i = 2, l = 0, r = 0; i <= len; i ++) {
    	// i 从 2 开始,代表后缀开始的位置,l = r = 0,一开始并没有区间 
        // 如果 i 在当前最右匹配区间 [l, r] 内
        if (i <= r) {
            z[i] = min(z[i - l + 1], 1ll * (r - i + 1));
            // 根据定义 1 到 r - l + 1 和 l 到 r 是相等的
			// 所以 i - l + 1 到 r - l + 1 和 i 到 r 是相等的
			// 因此以 i - l + 1 为标准,最大 LCP 最多就可以取 r - i + 1
			// 但是如果这个 r - i + 1 比 z[i - l + 1] 还要大的话,那当然取不了
			// 反之 r - i + 1 比 z[i - l + 1] 小,那也不能取大的
			// 因为只有 i - l + 1 到 r - l + 1 是相等的 
        }
        
        // 从 z[i] 开始尝试扩展匹配
        // 检查 s[1 + z[i]] 和 s[i + z[i]] 是否相等
        while (1 + z[i] <= len && i + z[i] <= len && s[1 + z[i]] == s[i + z[i]]) {
            z[i] ++;     // 匹配成功,LCP 长度 + 1
        }
        
        // 如果匹配后右边界超过当前最右匹配区间,则更新区间
        if (i + z[i] - 1 > r) {
            l = i;                // 新区间的左端点
            r = i + z[i] - 1;     // 新区间的右端点
        }
    }
}
 
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin >> (s + 1);
    len = strlen(s + 1);
    
    get_z();

    for (int i = 1; i <= len; i ++) {
        cout << z[i] << " ";
    }
    cout << "\n";
    
    return 0;
}
相关推荐
hetao17338372 分钟前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
Zootopia62644 分钟前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
longlongzihan1 小时前
从LeetCode 70. 爬楼梯看动态规划:如何精准推导状态转移方程?
c++·算法·leetcode·动态规划
2601_960356382 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
h_a_o777oah2 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO92 小时前
指针的算术运算详解
java·数据结构·算法
Coder-magician2 小时前
《代码随想录》刷题打卡day47:并查集-part01
数据结构·算法·图论
垆边人似月.3 小时前
VLAN 资源池(100~200 分档)
数据结构·算法
潼心1412o3 小时前
C++初阶(长期更新)第6讲:类和对象(下)
开发语言·c++·算法
星光开发者4 小时前
基于决策树随机森林算法的小说推荐系统的设计与实现-计算机毕设【课程设计】78485
vue.js·算法·微信小程序·django·php·课程设计·express