C++ 中的回文划分 III


假设我们有一个字符串 s,其中包含小写字母和一个整数 k。我们必须维护一些属性。这些是 -

  • 首先,我们必须更改 s 的某些字符(如果需要)为其他小写英文字母。
  • 然后将字符串 s 分割成 k 个子字符串,使得每个子字符串都是回文。

我们必须找到我们需要更改的字符的最小数量以分割字符串。

因此,如果字符串类似于“ababbc”且 k = 2,则答案将为 1,因为我们必须更改一个字符才能将其分成两个回文字符串。因此,如果我们将 c 更改为 b,或将倒数第二个 b 更改为 c,那么我们可以得到一个回文,例如“bbb”或“cbc”,另一个回文是“aba”。

为了解决这个问题,我们将遵循以下步骤 -

  • 定义一个大小为 105 x 105 的数组 memo。
  • 定义一个函数 solve(),它将接收 s、idx、k、一个二维数组 > dp,
  • 如果 idx 与 s 的大小相同,则 -
    • 返回当 k 为 0 时为 0,否则为 1000
  • 如果 memo[idx][k] 不等于 -1,则 -
    • 返回 memo[idx][k]
  • 如果 k <= 0,则 -
    • 返回 inf
  • ans := inf
  • 对于初始化 i := idx,当 i < s 的大小时,更新(i 增加 1),执行 -
    • ans := ans 和 dp[idx][i] + 调用函数 solve(s, i + 1, k - 1, dp) 的最小值
  • 返回 memo[idx][k] = ans
  • 从主方法中执行以下操作
  • n := s 的大小
  • 用 -1 填充 memo
  • 定义一个大小为 n x n 的二维数组 dp
  • 对于初始化 l := 2,当 l <= n 时,更新(l 增加 1),执行 -
    • 对于初始化 i := 0,j := l - 1,当 j < n 时,更新(j 增加 1),(i 增加 1),执行 -
      • 如果 l 等于 2,则 -
      • 当 s[i] 不等于 s[j] 时,dp[i][j] := true
      • 否则
        • 当 s[i] 等于 s[j] 时,dp[i][j] := dp[i + 1][j - 1] + 0
  • 返回 solve(s, 0, k, dp)

让我们看看以下实现以获得更好的理解 -

示例

 实时演示

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
class Solution {
public:
   int memo[105][105];
   lli solve(string s, int idx, int k, vector < vector <int> > &dp){
      if(idx == s.size()) {
         return k == 0? 0 : 1000;
      }
      if(memo[idx][k] != -1) return memo[idx][k];
      if(k <= 0)return INT_MAX;
      lli ans = INT_MAX;
      for(int i = idx; i < s.size(); i++){
         ans = min(ans, dp[idx][i] + solve(s, i + 1, k - 1, dp));
      }
      return memo[idx][k] = ans;
   }
   int palindromePartition(string s, int k) {
      int n = s.size();
      memset(memo, -1, sizeof(memo));
      vector < vector <int> > dp(n, vector <int>(n));
      for(int l =2; l <= n; l++){
         for(int i = 0, j = l - 1; j <n; j++, i++){
            if(l==2){
               dp[i][j] = !(s[i] == s[j]);
            }else{
               dp[i][j] = dp[i+1][j-1] + !(s[i] == s[j]);
            }
         }
      }
      return solve(s, 0, k, dp);
   }
};
main(){
   Solution ob;
   cout << (ob.palindromePartition("ababbc", 2));
}

输入

“ababbc”

输出

1

更新于: 2020年6月2日

151 次查看

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告