【3.10】贪心算法-找出对应 LCP 矩阵的字符串

一、题目

对任一由 n 个小写英文字母组成的字符串 word ,我们可以定义一个 n x n 的矩阵,并满足:

  • lcp[i][j] 等于子字符串 word[i,...,n-1]word[j,...,n-1] 之间的最长公共前缀的长度。

给你一个 n x n 的矩阵 lcp 。返回与 lcp 对应的、按字典序最小的字符串 word 。如果不存在这样的字符串,则返回空字符串。

对于长度相同的两个字符串 ab ,如果在 ab 不同的第一个位置,字符串 a 的字母在字母表中出现的顺序先于 b 中的对应字母,则认为字符串 a 按字典序比字符串 b 小。例如,"aabd" 在字典上小于 "aaca" ,因为二者不同的第一位置是第三个字母,而 'b' 先于 'c' 出现。

示例 1:

复制代码
输入:lcp = [[4,0,2,0],[0,3,0,1],[2,0,2,0],[0,1,0,1]]
输出:"abab"
解释:lcp 对应由两个交替字母组成的任意 4 字母字符串,字典序最小的是 "abab" 。

示例 2:

复制代码
输入:lcp = [[4,3,2,1],[3,3,2,1],[2,2,2,1],[1,1,1,1]]
输出:"aaaa"
解释:lcp 对应只有一个不同字母的任意 4 字母字符串,字典序最小的是 "aaaa" 。 

示例 3:

复制代码
输入:lcp = [[4,3,2,1],[3,3,2,1],[2,2,2,1],[1,1,1,3]]
输出:""
解释:lcp[3][3] 无法等于 3 ,因为 word[3,...,3] 仅由单个字母组成;因此,不存在答案。

提示:

  • 1 <= n == ``lcp.length == ``lcp[i].length <= 1000
  • 0 <= lcp[i][j] <= n

二、解题思路

要解决这个问题,我们可以使用贪心算法的思路来逐步构建字符串 word。贪心算法的核心思想是在每一步选择中都采取当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的。

具体步骤如下:

  1. 初始化字符串 :从第一个字符开始,逐步构建字符串 word

  2. 选择字符 :对于每个位置 i,我们需要选择一个字符 word[i],使得它与之前的字符串 word[0:i] 和矩阵 lcp 中的信息一致,并且按字典序最小。

  3. 验证 :选择字符后,验证它是否满足矩阵 lcp 中的信息。如果不满足,则返回空字符串。

  4. 迭代:继续选择下一个字符,直到构造完整个字符串。

具体的贪心策略如下:

  • 对于每个位置 i,我们尝试选择 az 中的每个字符,并检查它是否满足矩阵 lcp 中的信息。

  • 选择满足条件且按字典序最小的字符。

三、代码实现

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>

using namespace std;

string findTheString(vector<vector<int>>& lcp) {
    int n = lcp.size();
    string word(n, ' ');

    for (int i = 0; i < n; ++i) {
        for (char c = 'a'; c <= 'z'; ++c) {
            word[i] = c;
            bool valid = true;
            for (int j = 0; j <= i; ++j) {
                int prefix_len = 0;
                while (i + prefix_len < n && j + prefix_len < n && word[i + prefix_len] == word[j + prefix_len]) {
                    ++prefix_len;
                }
                if (lcp[i][j] != prefix_len || lcp[i][j] != lcp[j][i]) {
                    valid = false;
                    break;
                }
            }
            if (valid) {
                break;
            }
        }
        if (!valid) {
            return "";
        }
    }

    return word;
}

int main() {
    vector<vector<int>> lcp1 = {{4, 0, 2, 0}, {0, 3, 0, 1}, {2, 0, 2, 0}, {0, 1, 0, 1}};
    cout << findTheString(lcp1) << endl;  // 输出: "abab"

    return 0;
}
相关推荐
写个博客23 分钟前
代码随想录算法训练营第三十九天
算法
源码方舟1 小时前
【基于ALS模型的教育视频推荐系统(Java实现)】
java·python·算法·音视频
吃个早饭2 小时前
2025年第十六届蓝桥杯大赛软件赛C/C++大学B组题解
c语言·c++·蓝桥杯
fancy1661662 小时前
力扣top100 矩阵置零
人工智能·算法·矩阵
元亓亓亓2 小时前
LeetCode热题100--240.搜索二维矩阵--中等
算法·leetcode·矩阵
阿沁QWQ3 小时前
单例模式的两种设计
开发语言·c++·单例模式
六bring个六3 小时前
qtcreater配置opencv
c++·qt·opencv·计算机视觉·图形渲染·opengl
qwertyuiop_i3 小时前
pe文件二进制解析(用c/c++解析一个二进制pe文件)
c语言·c++·pe文件
明月看潮生3 小时前
青少年编程与数学 02-019 Rust 编程基础 09课题、流程控制
开发语言·算法·青少年编程·rust·编程与数学
oioihoii3 小时前
C++23 views::slide (P2442R1) 深入解析
linux·算法·c++23