zoukankan      html  css  js  c++  java
  • 判断一个字符串在至多删除k个字符后是否为回文串

    转自: http://www.careercup.com/question?id=6287528252407808

    问题描述:

    A k-palindrome is a string which transforms into a palindrome on removing at most k characters.
    Given a string S, and an interger K, print "YES" if S is a k-palindrome; otherwise print "NO".
    Constraints:
    S has at most 20,000 characters.
    0<=k<=30
    Sample Test Case#1:
    Input - abxa 1
    Output - YES
    Sample Test Case#2:
    Input - abdxa 1
    Output – No

    解答:懒得写了,下面这段通俗易懂,就先将就着看吧

    The question asks if we can transform the given string S into its reverse deleting at most K letters.
    We could modify the traditional Edit-Distance algorithm, considering only deletions, and check if this edit distance is <= K. There is a problem though. S can have length = 20,000 and the Edit-Distance algorithm takes O(N^2). Which is too slow.
    (From here on, I'll assume you're familiar with the Edit-Distance algorithm and its DP matrix)
    However, we can take advantage of K. We are only interested *if* manage to delete K letters. This means that any position more than K positions away from the main diagonal is useless because its edit distance must exceed those K deletions.
    Since we are comparing the string with its reverse, we will do at most K deletions and K insertions (to make them equal). Thus, we need to check if the ModifiedEditDistance is <= 2*K
    Here's the code:

       1:  int ModifiedEditDistance(const string& a, const string& b, int k) {
       2:      int i, j, n = a.size();
       3:      // for simplicity. we should use only a window of size 2*k+1 or 
       4:      // dp[2][MAX] and alternate rows. only need row i-1
       5:      int dp[MAX][MAX];
       6:      memset(dp, 0x3f, sizeof dp);    // init dp matrix to a value > 1.000.000.000
       7:      for (i = 0 ; i < n; i++)
       8:          dp[i][0] = dp[0][i] = i;
       9:   
      10:      for (i = 1; i <= n; i++) {
      11:          int from = max(1, i-k), to = min(i+k, n);
      12:          for (j = from; j <= to; j++) {
      13:              if (a[i-1] == b[j-1])            // same character
      14:                  dp[i][j] = dp[i-1][j-1];    
      15:              // note that we don't allow letter substitutions
      16:              
      17:              dp[i][j] = min(dp[i][j], 1 + dp[i][j-1]); // delete character j
      18:              dp[i][j] = min(dp[i][j], 1 + dp[i-1][j]); // insert character i
      19:          }
      20:      }
      21:      return dp[n][n];
      22:  }
      23:  cout << ModifiedEditDistance("abxa", "axba", 1) << endl;  // 2 <= 2*1 - YES
      24:  cout << ModifiedEditDistance("abdxa", "axdba", 1) << endl; // 4 > 2*1 - NO
      25:  cout << ModifiedEditDistance("abaxbabax", "xababxaba", 2) << endl; // 4 <= 2*2 - YES

    We only process 2*K+1 columns per row. So this algorithm works in O(N*K) which is fast enough.

  • 相关阅读:
    mysql8.0.20安装
    MySQL EXPLAIN结果集分析
    初次安装aliSql
    升级vim到8.0
    REPL环境对语言的帮助
    Python环境搭建及pip的使用
    mysql数据库分库分表(Sharding)
    Git的使用
    Promise的初步认识
    对引用的文件起别名
  • 原文地址:https://www.cnblogs.com/xubenben/p/3398404.html
Copyright © 2011-2022 走看看