Leetcode2976. 转换字符串的最小成本 I

Every day a Leetcode

题目来源:2976. 转换字符串的最小成本 I

解法1:最短路

建图,从 original[i] 向 changed[i] 连边,边权为 cost[i]。没边的边权设为 INF。

然后用 Floyd 算法求图中任意两点最短路,得到 g 矩阵。这里得到的 g[i][j] 表示字母 i 通过若干次替换操作变成字母 j 的最小成本。

最后累加所有 g[original[i]],即为答案。如果中间遇到边权为 INF,说明无法转换,返回 −1。

代码:

/*
 * @lc app=leetcode.cn id=2976 lang=cpp
 *
 * [2976] 转换字符串的最小成本 I
 */

// @lc code=start
class Solution
{
private:
    const int INF = 1e9;

public:
    long long minimumCost(string source, string target, vector<char> &original, vector<char> &changed, vector<int> &cost)
    {
        // 邻接矩阵
        vector<vector<long long>> g(26, vector<long long>(26, INF));
        // 初始化
        for (int i = 0; i < 26; i++)
            g[i][i] = 0;
        // 建图
        for (int i = 0; i < original.size(); i++)
        {
            int x = original[i] - 'a', y = changed[i] - 'a';
            g[x][y] = min(g[x][y], (long long)cost[i]);
        }
        // Floyd 算法求最短路
        for (int k = 0; k < 26; k++)
            for (int i = 0; i < 26; i++)
                for (int j = 0; j < 26; j++)
                    g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
        // 计算最小成本
        long long minCost = 0;
        for (int i = 0; i < source.size(); i++)
        {
            int x = source[i] - 'a', y = target[i] - 'a';
            if (x != y)
            {
                // x 不能变成 y,无解
                if (g[x][y] >= INF)
                    return -1;
                // 否则答案增加把 x 改成 y 的最小代价
                minCost += g[x][y];
            }
        }
        return minCost;
    }
};
// @lc code=end

结果:

Leetcode2976. 转换字符串的最小成本 I_第1张图片

复杂度分析:

时间复杂度:O(n+m+∣Σ∣3),其中 n 为字符串 source/target 的长度,m 为数组 original/changed/cost 的长度,∣Σ∣ 为字符集合的大小,本题中字符均为小写字母,所以 ∣Σ∣=26。

空间复杂度:O(∣Σ∣2),其中 ∣Σ∣ 为字符集合的大小,本题中字符均为小写字母,所以 ∣Σ∣=26。

你可能感兴趣的:(Every,day,a,LeetCode,C++,数据结构与算法,leetcode,最短路)