📌  相关文章
📜  最小化删除以将字符串减小到大小 1,其中第 i 个删除,可以删除第 (X+i-1) 个字符的 N/2^i 个出现

📅  最后修改于: 2022-05-13 01:56:09.628000             🧑  作者: Mango

最小化删除以将字符串减小到大小 1,其中第 i 个删除,可以删除第 (X+i-1) 个字符的 N/2^i 个出现

给定长度为N的字符串str和一个字符X ,其中N的形式总是2 k ,任务是找到将字符串的大小减小到1所需的最小替换操作,其中第 i删除, N/2 i (X + i – 1)字符的出现可以从字符串的前面或后面删除。

例子:

方法:给定的问题可以通过使用与二分搜索具有相似结构的递归来解决。在每次删除期间,可以观察到有 2 个可能的选择。它们如下:

  1. 将给定字符串的前半部分的所有字符替换为“X”,并递归调用 X = X + 1 的剩余半部分。
  2. 或者,用“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)