最小化删除以将字符串减小到大小 1,其中第 i 个删除,可以删除第 (X+i-1) 个字符的 N/2^i 个出现
给定长度为N的字符串str和一个字符X ,其中N的形式总是2 k ,任务是找到将字符串的大小减小到1所需的最小替换操作,其中第 i次删除, N/2 i 第(X + i – 1)个字符的出现可以从字符串的前面或后面删除。
例子:
Input: str = “CDAAAABB”, X = ‘A’
Output: 4
Explanation: Replacement operations on the given string can be done as:
- Replace ‘C’ at 1st index with ‘A’.
- Replace ‘D’ at 2nd index with ‘A’.
- Replace ‘A’ at 5th index with ‘D’.
- Replace ‘A’ at 6th index with ‘C’.
Therefore, the string becomes str = “AAAADCBB”. During the 1st deletion (8/21) occurrences of (A+1-1)th character can be removed from the front of the string. Therefore, the string becomes str = “DCBB”. Similarly, during the 2nd deletion (8/22) occurrences of (A+2-1)th i.e, ‘B’ character can be removed from the back of the string. Therefore, the string becomes str = “DC”. Similarly, after the 3rd deletion, the string becomes str = “D” having length as 1. Therefore, the number of required replacement operations are 4 which is the minimum possible.
Input: str = “QRQP”, X = ‘P’
Output: 1
方法:给定的问题可以通过使用与二分搜索具有相似结构的递归来解决。在每次删除期间,可以观察到有 2 个可能的选择。它们如下:
- 将给定字符串的前半部分的所有字符替换为“X”,并递归调用 X = X + 1 的剩余半部分。
- 或者,用“X”替换给定字符串后半部分的所有字符,并递归调用 X = X + 1 的剩余一半。
因此,使用上述观察结果创建了一个递归函数,该函数通过计算字符串前半部分需要替换为 X 的索引数量并递归调用剩余一半,从而从两种可能性中取出最小移动,反之亦然.
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// Recursive function to find minimum
// replacements required to reduce the
// size of the given string to 1
int minReplacment(string s, char x)
{
// Base Case
if (s.size() == 1) {
return s[0] != x;
}
// Stores the middle index
int mid = s.size() / 2;
// Recursive call for left half
int cntl = minReplacment(
string(s.begin(), s.begin() + mid), x + 1);
cntl += s.size() / 2
- count(s.begin() + mid, s.end(), x);
// Recursive call for right half
int cntr = minReplacment(
string(s.begin() + mid, s.end()), x + 1);
cntr += s.size() / 2
- count(s.begin(), s.begin() + mid, x);
// Return Answer
return min(cntl, cntr);
}
// Driver Code
int main()
{
int N = 8;
string str = "CDAAAABB";
char X = 'A';
cout << minReplacment(str, X);
return 0;
}
Java
/*package whatever //do not write package name here */
// Java code for the above approach
import java.util.*;
class GFG {
public static int count(String str, char c)
{
int ct = 0;
for (int i = 0; i < str.length(); i++) {
char currChar = str.charAt(i);
if (currChar == c)
ct += 1;
}
return ct;
}
// Recursive function to find minimum
// replacements required to reduce the
// size of the given string to 1
static int minReplacment(String s, char x)
{
// Base Case
if (s.length() == 1) {
if (s.charAt(0) == x)
return 1;
return 0;
}
// Stores the middle index
int mid = s.length() / 2;
// Recursive call for left half
char p = (char)(x + 1);
int cntl = minReplacment(s.substring(0, mid), p);
cntl = cntl + s.length() / 2
- count(s.substring(mid, s.length()), x);
// Recursive call for right half
char t = (char)(x + 1);
int cntr = minReplacment(
s.substring(mid, s.length()), t);
cntr = cntr + s.length() / 2
- count(s.substring(0, mid), x);
// Return Answer
return Math.min(cntl + 1, cntr);
}
// Driver Code
public static void main(String[] args)
{
int N = 8;
String str = "CDAAAABB";
char X = 'A';
System.out.println(minReplacment(str, X));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python 3 implementation for the above approach
# Recursive function to find minimum
# replacements required to reduce the
# size of the given string to 1
def minReplacment(s, x):
# Base Case
if (len(s) == 1):
return s[0] != x
# Stores the middle index
mid = len(s) // 2
# Recursive call for left half
cntl = minReplacment(
s[:mid], chr(ord(x) + 1))
cntl += len(s) // 2 - s[mid:].count(x)
# Recursive call for right half
cntr = minReplacment(
s[mid:], chr(ord(x) + 1))
cntr += len(s) // 2 - s[:mid].count(x)
# Return Answer
return min(cntl, cntr)
# Driver Code
if __name__ == "__main__":
N = 8
st = "CDAAAABB"
X = 'A'
print(minReplacment(st, X))
# This code is contributed by ukasp.
C#
/*package whatever //do not write package name here */
// C# code for the above approach
using System;
public class GFG {
public static int count(String str, char c)
{
int ct = 0;
for (int i = 0; i < str.Length; i++) {
char currChar = str[i];
if (currChar == c)
ct += 1;
}
return ct;
}
// Recursive function to find minimum
// replacements required to reduce the
// size of the given string to 1
static int minReplacment(String s, char x)
{
// Base Case
if (s.Length == 1) {
if (s[0] == x)
return 1;
return 0;
}
// Stores the middle index
int mid = s.Length / 2;
// Recursive call for left half
char p = (char)(x + 1);
int cntl = minReplacment(s.Substring(0, mid), p);
cntl = cntl + s.Length / 2
- count(s.Substring(mid, s.Length-mid), x);
// Recursive call for right half
char t = (char)(x + 1);
int cntr = minReplacment(
s.Substring(mid, s.Length-mid), t);
cntr = cntr + s.Length / 2
- count(s.Substring(0, mid), x);
// Return Answer
return Math.Min(cntl + 1, cntr);
}
// Driver Code
public static void Main(String[] args)
{
String str = "CDAAAABB";
char X = 'A';
Console.WriteLine(minReplacment(str, X));
}
}
// This code is contributed by shikhasingrajput
Javascript
4
时间复杂度: O(N*log N)
辅助空间: O(1)