zoukankan      html  css  js  c++  java
  • 【leet-code】712. 两个字符串的最小ASCII删除和

    题目描述

    给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和。

    示例 1:

    输入: s1 = "sea", s2 = "eat"
    输出: 231
    解释: 在 "sea" 中删除 "s" 并将 "s" 的值(115)加入总和。
    在 "eat" 中删除 "t" 并将 116 加入总和。
    结束时,两个字符串相等,115 + 116 = 231 就是符合条件的最小和。

    示例 2:

    输入: s1 = "delete", s2 = "leet"
    输出: 403
    解释: 在 "delete" 中删除 "dee" 字符串变成 "let",
    将 100[d]+101[e]+101[e] 加入总和。在 "leet" 中删除 "e" 将 101[e] 加入总和。
    结束时,两个字符串都等于 "let",结果即为 100+101+101+101 = 403 。
    如果改为将两个字符串转换为 "lee" 或 "eet",我们会得到 433 或 417 的结果,比答案更大。

    注意:

    0 < s1.length, s2.length <= 1000。
    所有字符串中的字符ASCII值在[97, 122]之间。

    算法

    这是动态规划的一道题目,凡是这类题目都需要拿起笔来推演过程,在过程中就能发现状态转移方程。下面以s1 = "delete", s2 = "leet"为例给出更新的表格,dp[i][j]代表s1(0,j)与s2(0,1)两个字符串要想相同需要删除的字符

    s2s1 d e l e t e
    l d+l d+l+e d+e d+e+e d+e+e+t d+e+e+t+e
    e d+l+e d+l d+e+e d+e d+e+t d+e+e+t
    e d+l+e+e d+l+e d+e+e+e d+e+e d+e+e+t d+e+t
    t d+l+e+e+t d+l+e+t d+e+e+e+t d+e+e+t d+e+e d+e+e+e

    代码

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <numeric>
    using namespace std;
    
    class Solution{
    public:
        int minimumDeleteSum(string s1, string s2) {
            if (s1 == "" && s2 == "")
                return 0;
            else if (s1 == "")
                return accumulate(s2.begin(), s2.end(), 0);
            else if (s2 == "")
                return accumulate(s1.begin(), s1.end(), 0);
            else
            {
                // parameters
                int col = s1.size();
                int row = s2.size();
                int dp[row][col];   // dp[i][j]-两个字符串s1(0, j)与s2(0, i)的最小ASCII删除和
    
                // initialize
                bool total_switch = true;
                if (s1[0] == s2[0])
                {
                    dp[0][0] = 0;
                    total_switch = false;
                }
                else
                    dp[0][0] = s1[0] + s2[0];
                
                bool first_time = true;
                if (total_switch == false)
                    first_time = false;
                for (int i = 1; i < col; i++)
                {
                    if (s1[i] == s2[0] && first_time == true)
                    {
                        dp[0][i] = dp[0][i-1] - s2[0];
                        first_time = false;
                    }
                    else
                        dp[0][i] = dp[0][i-1] + s1[i];
                }
    
                first_time = true;
                if (total_switch == false)
                    first_time = false;
                for (int i = 1; i < row; i++)
                {
                    if (s1[0] == s2[i] && first_time == true)
                    {
                        dp[i][0] = dp[i-1][0] - s1[0];
                        first_time = false;
                    }
                    else
                        dp[i][0] = dp[i-1][0] + s2[i];
                }
    
                // update dp[i][j]
                for (int i = 1; i < row; i++)
                {
                    for (int j = 1; j < col; j++)
                    {
                        // 更新条件
                        if (s1[j] == s2[i])
                            dp[i][j] = dp[i-1][j-1];
                        else
                            dp[i][j] = min((dp[i-1][j] + s2[i]), dp[i][j-1] + s1[j]);
                    }
                }
                return dp[row-1][col-1];
            }
        }
    };
    
    int main()
    {
        Solution s;
        string s1 = "caabcccaccccca", s2 = "cacbaaac";
        cout << "最小和是:
    " << s.minimumDeleteSum(s1, s2) << endl;
        return 0;
    }
    
  • 相关阅读:
    (转)Android IPC机制详解
    (转)android 多线程
    (转)android进程间通信:使用AIDL
    (转)如何调用SQLITE工具查看数据库
    (转)Android 自动 打包
    (转)如何手动编译一个APK
    (转)编译Android源码的全过程
    Js打造层拖动实例:网站菜单拖拽移位效果
    JS鼠标悬停时动态翻滚的紫色导航条
    jQuery1.3.2竖向的伸缩菜单
  • 原文地址:https://www.cnblogs.com/shayue/p/10412465.html
Copyright © 2011-2022 走看看