LeetCode 2573. 找出对应 LCP 矩阵的字符串

LeetCode 2573. 找出对应 LCP 矩阵的字符串

题目描述

给你一个 n x n 的矩阵 lcp,其中 lcp[i][j] 表示字符串 s 从下标 i 开始和从下标 j 开始的最长公共前缀(LCP)的长度。你需要还原出由小写字母组成的字符串 s,如果不存在这样的字符串则返回空串。

示例:

复制代码
输入:lcp = [[3,0,0],[0,2,1],[0,1,2]]
输出:"abb"
解释:字符串 "abb" 对应的 LCP 矩阵如上。

解题思路

关键性质

  • lcp[i][j] > 0,则必有 s[i] == s[j],且 lcp[i][j] = 1 + lcp[i+1][j+1](当 ij 不是最后一个字符时)。
  • s[i] == s[j],则 lcp[i][j] = 1 + lcp[i+1][j+1](如果 i+1j+1 均未越界)。
  • s[i] != s[j],则 lcp[i][j] = 0

根据这些性质,我们可以先构造一个可能的字符串,再验证其与给定矩阵是否一致。

算法步骤

1. 贪心构造字符串
  • 使用一个指针 i 指向第一个未确定字符的位置(初始为 0)。
  • 按照字母 'a''z' 的顺序尝试填充:
    • 对于当前字母 c,遍历 jin-1
      • 如果 lcp[i][j] > 0,说明 s[j] 必须与 s[i] 相等,因此将 s[j] 设为 c
    • 然后移动 i 到第一个仍未被赋值的下标(s[i] == 0)。
    • 如果 i == n,说明所有位置都已填满,提前结束。
  • 若 26 个字母用完后仍有未赋值的位置,说明无法构造,返回空串。
2. 验证矩阵一致性
  • 从后向前遍历所有下标对 (i, j),计算在构造出的字符串 s 中应有的 LCP 值:
    • s[i] != s[j],则实际值应为 0。
    • s[i] == s[j]
      • i == n-1j == n-1,则实际值为 1。
      • 否则实际值为 1 + lcp[i+1][j+1]
  • 如果任何一对的 lcp[i][j] 与计算值不等,则返回空串。
  • 验证通过后返回构造的字符串。

代码实现

cpp 复制代码
class Solution {
public:
    string findTheString(vector<vector<int>>& lcp) {
        int n = lcp.size();
        string s(n, 0);           // 初始化全为0,表示未赋值
        int i = 0;

        // 贪心构造阶段
        for (char c = 'a'; c <= 'z'; c++) {
            // 将所有与位置 i 相等的字符设为当前字母 c
            for (int j = i; j < n; j++) {
                if (lcp[i][j] > 0)
                    s[j] = c;
            }
            // 移动 i 到下一个未赋值的位置
            while (i < n && s[i] != 0) i++;
            if (i == n) break;      // 所有位置已填满
        }

        // 如果还有未赋值的位置,无解
        if (i < n) return "";

        // 验证阶段:从后向前检查 LCP 矩阵是否一致
        for (int i = n - 1; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                int actual = (s[i] != s[j]) ? 0 : 
                             (i == n - 1 || j == n - 1) ? 1 : 
                             lcp[i + 1][j + 1] + 1;
                if (lcp[i][j] != actual)
                    return "";
            }
        }
        return s;
    }
};

复杂度分析

  • 时间复杂度:构造阶段 O(26·n) ≈ O(n),验证阶段 O(n²),因此总时间复杂度为 O(n²)。
  • 空间复杂度:O(n),用于存储结果字符串。

关键细节说明

  1. 构造阶段为什么可以贪心?

    • 因为 LCP 矩阵的性质决定了,如果 lcp[i][j] > 0,那么 s[i]s[j] 必然相等,且所有与 s[i] 相等的字符构成一个等价类。我们只需按顺序为每个等价类分配一个不同的字母(最多 26 个)即可。
  2. 验证时的计算方式

    • 从后向前计算是为了利用已经验证过的 lcp[i+1][j+1] 值,避免重复计算。
    • s[i] == s[j] 时,LCP 至少为 1,加上从下一个位置开始的 LCP 即可得到正确值。
  3. 为什么需要验证?

    • 贪心构造只是保证了字符相等关系与矩阵中正数的对应,但矩阵中还有为 0 的值需要检查是否与字符不等关系一致。此外,矩阵的数值本身也必须满足递归关系,验证阶段可以捕获所有矛盾。
相关推荐
斯内科1 小时前
四胞胎素数:找出‌个位数分别是 1、3、7、9‌,且‌十位及更高位数字完全相同‌的质数,例如 11、13、17、19
算法·质数·素数·四胞胎素数
Hello.Reader1 小时前
算法基础(十二)——主方法:快速求解常见递归式
算法
小O的算法实验室2 小时前
2026年IEEE TITS,面向按需外卖配送调度的特定问题知识与基于学习元启发式算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
加勒比海带662 小时前
目标检测算法——农林行业数据集汇总附下载链接【Plant】
大数据·图像处理·人工智能·算法·目标检测
洛水水2 小时前
【力扣100题】23. 螺旋矩阵
算法·leetcode·矩阵
影sir2 小时前
不同测试数据下,该如何选择算法
算法·深度优先
潇湘散客2 小时前
CAX软件插件化设计实现牛刀小试
c++·算法·图形学·opengl
速易达网络3 小时前
2026,视觉算法正在经历一场静默革命
算法
WBluuue3 小时前
Codeforces 1094 Div1+2(ABCDE)
c++·算法
TENSORTEC腾视科技3 小时前
腾视科技大模型一体机解决方案:低成本私有化落地,重塑行业智能应用新格局
大数据·人工智能·科技·算法·ai·零售·大模型一体机