给定一个字符串str和[L, R, K]形式的Q查询,任务是找出[L, R]中最多允许K 个变化的字符串的字符是否可以重新排列以使字符串回文.对于每个查询,如果它可以成为回文字符串,则打印“YES” ,否则打印“NO” 。
例子:
Input: str = “GeeksforGeeks”, Q = { { 1, 5, 3 }, { 5, 7, 0 }, { 8, 11, 3 }, {3, 10, 5 }, { 0, 9, 5 } }
Output:
YES
NO
YES
YES
YES
Explanation:
queries[0] : substring = “eeksf”, could be changed to “eekee” which is palindrome.
queries[1] : substring = “for”, is not palindrome and can’t be made palindromic after replacing atmost 0 character..
queries[2] : substring = “Gee”, could be changed to “GeG” which is palindrome.
queries[3] : substring = “ksforGee”, could be changed to “ksfoofsk” which is palindrome.
queries[4] : substring = “GeeksforGe”, could be changed to “GeeksskeeG” which is palindrome.
Input: str = “abczwerte”, Q = { { 3, 7, 4 }, { 1, 8, 10 }, { 0, 3, 1 } }
Output:
YES
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,则打印“YES”,否则打印“NO” 。
下面是上述方法的实现:
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 是字符串的长度。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live