📌  相关文章
📜  通过为Q查询替换K个字符来检查子字符串是否可以回文

📅  最后修改于: 2021-04-27 23:32:23             🧑  作者: Mango

给定一个字符串strQ查询的形式[L,R,K],任务是寻找是否从[L,R]用至多为k的变化是允许的字符串的字符可以重新排列,使字符串回文与否。对于每个查询,如果可以变成回文字符串,则打印“ YES” ,否则打印“ NO”
例子:

方法:可以使用动态编程解决此问题。

  • 创建一个二维矩阵(例如dp [i] [j] ),其中dp [i] [j]表示子串str [0…j]中第i个字符的计数。
  • 以下是上述方法的重复关系:
    • 如果str [i]等于str [j],则dp [i] [j] = 1 + dp [i] [j-1]
    • 如果str [i]不等于str [j],则dp [i] [j] = dp [i] [j-1]
    • 如果j等于0,然后DP [i] [j]将其等于第i个字符的第一个字符中的一个。
  • 对于每个查询,通过简单的关系找出子字符串str [L…R]中每个字符的计数:
count =  dp[i][right] - dp[i][left] + (str[left] == i + 'a').
  • 获取不匹配对的数量。
  • 现在我们需要将不匹配的一半字符转换为其余字符。如果不匹配字符的半数小于或等于K,打印“是”,否则打印“否”

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find whether string can
// be made palindromic or not for each queries
void canMakePaliQueries(
    string str,
    vector >& Q)
{
    int n = str.length();
 
    // To store the count of ith character
    // of substring str[0...i]
    vector > dp(
        26,
        vector(n, 0));
 
    for (int i = 0; i < 26; i++) {
 
        // Current character
        char currentChar = i + 'a';
        for (int j = 0; j < n; j++) {
 
            // Update dp[][] on the basis
            // recurrence relation
            if (j == 0) {
                dp[i][j]
                    = (str[j] == currentChar);
            }
            else {
                dp[i][j]
                    = dp[i][j - 1]
                      + (str[j] == currentChar);
            }
        }
    }
 
    // For each queries
    for (auto query : Q) {
        int left = query[0];
        int right = query[1];
        int k = query[2];
 
        // To store the count of
        // distinct character
        int unMatchedCount = 0;
        for (int i = 0; i < 26; i++) {
 
            // Find occurrence of i + 'a'
            int occurrence
                = dp[i][right]
                  - dp[i][left]
                  + (str[left] == (i + 'a'));
 
            if (occurrence & 1)
                unMatchedCount++;
        }
 
        // Half the distinct Count
        int ans = unMatchedCount / 2;
 
        // If half the distinct count is
        // less than equals to K then
        // palindromic string can be made
        if (ans <= k) {
            cout << "YES\n";
        }
        else {
            cout << "NO\n";
        }
    }
}
 
// Driver Code
int main()
{
    // Given string str
    string str = "GeeksforGeeks";
 
    // Given Queries
    vector > Q;
    Q = { { 1, 5, 3 }, { 5, 7, 0 },
 { 8, 11, 3 }, { 3, 10, 5 },
{ 0, 9, 5 } };
 
    // Function call
    canMakePaliQueries(str, Q);
    return 0;
}


Java
// Java program for the above approach
class GFG{
 
// Function to find whether String can be
// made palindromic or not for each queries
static void canMakePaliQueries(String str,
                               int [][]Q)
{
    int n = str.length();
 
    // To store the count of ith character
    // of subString str[0...i]
    int [][]dp = new int[26][n];
 
    for(int i = 0; i < 26; i++)
    {
        
       // Current character
       char currentChar = (char)(i + 'a');
       for(int j = 0; j < n; j++)
       {
        
          // Update dp[][] on the basis
          // recurrence relation
          if (j == 0)
          {
              dp[i][j] = (str.charAt(j) ==
                          currentChar) ? 1 : 0;
          }
          else
          {
              dp[i][j] = dp[i][j - 1] +
                         ((str.charAt(j) ==
                           currentChar) ? 1 : 0);
          }
       }
    }
 
    // For each queries
    for(int []query : Q)
    {
       int left = query[0];
       int right = query[1];
       int k = query[2];
        
       // To store the count of
       // distinct character
       int unMatchedCount = 0;
       for(int i = 0; i < 26; i++)
       {
            
          // Find occurrence of i + 'a'
          int occurrence = dp[i][right] -
                           dp[i][left] +
                           (str.charAt(left) ==
                           (i + 'a') ? 1 : 0);
           
          if (occurrence % 2 == 1)
              unMatchedCount++;
       }
        
       // Half the distinct Count
       int ans = unMatchedCount / 2;
        
       // If half the distinct count is
       // less than equals to K then
       // palindromic String can be made
       if (ans <= k)
       {
           System.out.print("YES\n");
       }
       else
       {
           System.out.print("NO\n");
       }
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given a String str
    String str = "GeeksforGeeks";
 
    // Given Queries
    int [][]Q = { { 1, 5, 3 },
                  { 5, 7, 0 },
                  { 8, 11, 3 },
                  { 3, 10, 5 },
                  { 0, 9, 5 } };
                   
    // Function call
    canMakePaliQueries(str, Q);
}
}
 
// This code is contributed by gauravrajput1


Python3
# Python3 program for
# the above approach
 
# Function to find whether
# string can be made palindromic
# or not for each queries
def canMakePaliQueries(str, Q):
    n = len(str)
 
    # To store the count of
    # ith character of substring
    # str[0...i]
    dp = [[0 for i in range(n)]
             for j in range(26)]\
     
    for i in range(26):
 
        # Current character
        currentChar = chr(i + ord('a'))
         
        for j in range(n):
 
            # Update dp[][] on the basis
            # recurrence relation
            if(j == 0):
                dp[i][j] = (str[j] ==
                            currentChar)
            else:
                dp[i][j] = dp[i][j - 1] +
                           (str[j] == currentChar)
 
    # For each queries
    for query in Q:
        left = query[0]
        right = query[1]
        k = query[2]
 
        # To store the count of
        # distinct character
        unMatchedCount = 0
 
        for i in range(26):
 
            # Find occurrence of
            # i + 'a'
            occurrence = dp[i][right] -
                         dp[i][left] +
                         (str[left] ==
                          chr(i + ord('a')))
                 
            if(occurrence & 1):
                unMatchedCount += 1
 
         # Half the distinct Count
        ans = int(unMatchedCount / 2)
 
        # If half the distinct count is
        # less than equals to K then
        # palindromic string can be made
        if(ans <= k):
            print("YES")
        else:
            print("NO")
 
# Driver Code
 
# Given string str
str = "GeeksforGeeks"
 
# Given Queries
Q = [[1, 5, 3],
     [5, 7, 0],
     [8, 11, 3],
     [3, 10, 5],
     [0, 9, 5]]
 
# Function call
canMakePaliQueries(str, Q)
 
# This code is contributed by avanitrachhadiya2155


C#
// C# program for the above approach
using System;
class GFG{
 
// Function to find whether String can be
// made palindromic or not for each queries
static void canMakePaliQueries(String str,
                               int [,]Q)
{
    int n = str.Length;
 
    // To store the count of ith character
    // of subString str[0...i]
    int [,]dp = new int[26, n];
 
    for(int i = 0; i < 26; i++)
    {
        
       // Current character
       char currentChar = (char)(i + 'a');
       for(int j = 0; j < n; j++)
       {
        
          // Update [,]dp on the basis
          // recurrence relation
          if (j == 0)
          {
              dp[i,j] = (str[j] ==
                         currentChar) ? 1 : 0;
          }
          else
          {
              dp[i,j] = dp[i, j - 1] +
                         ((str[j] ==
                           currentChar) ? 1 : 0);
          }
       }
    }
 
    // For each queries
    for(int l = 0; l < Q.GetLength(0);l++)
    {
        int []query = GetRow(Q,l);
       int left = query[0];
       int right = query[1];
       int k = query[2];
        
       // To store the count of
       // distinct character
       int unMatchedCount = 0;
       for(int i = 0; i < 26; i++)
       {
            
          // Find occurrence of i + 'a'
          int occurrence = dp[i, right] -
                           dp[i, left] +
                           (str[left] ==
                           (i + 'a') ? 1 : 0);
           
          if (occurrence % 2 == 1)
              unMatchedCount++;
       }
        
       // Half the distinct Count
       int ans = unMatchedCount / 2;
        
       // If half the distinct count is
       // less than equals to K then
       // palindromic String can be made
       if (ans <= k)
       {
           Console.Write("YES\n");
       }
       else
       {
           Console.Write("NO\n");
       }
    }
}
 public static int[] GetRow(int[,] matrix, int row)
  {
    var rowLength = matrix.GetLength(1);
    var rowVector = new int[rowLength];
 
    for (var i = 0; i < rowLength; i++)
      rowVector[i] = matrix[row, i];
 
    return rowVector;
  }
// Driver Code
public static void Main(String[] args)
{
     
    // Given a String str
    String str = "GeeksforGeeks";
 
    // Given Queries
    int [,]Q = { { 1, 5, 3 },
                 { 5, 7, 0 },
                 { 8, 11, 3 },
                 { 3, 10, 5 },
                 { 0, 9, 5 } };
                   
    // Function call
    canMakePaliQueries(str, Q);
}
}
 
// This code is contributed by Princi Singh


输出:
YES
NO
YES
YES
YES



时间复杂度: O(26 * N),其中N是字符串的长度。
辅助空间: O(26 * N),其中N是字符串的长度。