📜  使用固定长度的子序列最小化从任何长度为 K 的随机字符串形成字符串S 的步骤

📅  最后修改于: 2021-09-24 05:04:55             🧑  作者: Mango

给定一个字符串S组成的N个字符和整数K,一个正的,则任务是找到操作的最小数量需要产生从大小为K的随机字符串临时字符串S和从随机字符串中插入任何固定长度的子序列在随机字符串。如果无法生成字符串S ,则打印“-1”

例子:

方法:这个问题可以通过使用贪心方法和二分搜索来解决。请按照以下步骤解决此问题:

  • 初始化 一个 数组,比如说amount[] ,它存储字符串S的每个字符的频率。
  • 使用变量i在范围[0, N – 1] 中迭代,并将数组amount[] 中当前字符的频率增加1
  • 在字符串S 中查找 count 个唯一字符并将其存储在一个变量中,例如count
  • 如果计数大于N,则返回-1
  • 现在,执行二进制搜索以查找结果字符串并执行以下步骤:
  • 将两个变量初始化为10 50
  • 迭代直到(high-low)的值大于1 ,执行以下步骤:
    • total的值更新为0并将mid 更新(high + low) / 2
    • 使用变量i在范围[0, 25] 中迭代,如果amount[i]的值大于0 ,则将总数增加(amounts[i] – 1)/mid + 1
    • 如果 总数小于等于N ,则将high的值更新为mid 。否则,将low的值更新为mid
  • 完成上述步骤后,打印high的值并在[0, 25]范围内迭代,并打印结果字符串。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the minimum number
// of string required to generate
// the original string
void findString(string S, int N)
{
    // Stores the frequency of each
    // character of String S
    int amounts[26];
 
    // Iterate over the range [0, 25]
    for (int i = 0; i < 26; i++) {
        amounts[i] = 0;
    }
 
    // Stores the frequency of each
    // character of String S
    for (int i = 0; i < S.length(); i++) {
        amounts[int(S[i]) - 97]++;
    }
 
    int count = 0;
 
    // Count unique characters in S
    for (int i = 0; i < 26; i++) {
        if (amounts[i] > 0)
            count++;
    }
 
    // If unique characters is greater
    // then N, then return -1
    if (count > N) {
        cout << "-1";
    }
 
    // Otherwise
    else {
 
        string ans = "";
        int high = 100001;
        int low = 0;
        int mid, total;
 
        // Perform Binary Search
        while ((high - low) > 1) {
 
            total = 0;
 
            // Find the value of mid
            mid = (high + low) / 2;
 
            // Iterate over the range
            // [0, 26]
            for (int i = 0; i < 26; i++) {
 
                // If the amount[i] is
                // greater than 0
                if (amounts[i] > 0) {
                    total += (amounts[i] - 1)
                                 / mid
                             + 1;
                }
            }
 
            // Update the ranges
            if (total <= N) {
                high = mid;
            }
            else {
                low = mid;
            }
        }
 
        cout << high << " ";
 
        total = 0;
 
        // Find the resultant string
        for (int i = 0; i < 26; i++) {
 
            if (amounts[i] > 0) {
                total += (amounts[i] - 1)
                             / high
                         + 1;
 
                for (int j = 0;
                     j < ((amounts[i] - 1)
                              / high
                          + 1);
                     j++) {
 
                    // Generate the subsequence
                    ans += char(i + 97);
                }
            }
        }
 
        // If the length of resultant
        // string is less than N than
        // add a character 'a'
        for (int i = total; i < N; i++) {
            ans += 'a';
        }
 
        reverse(ans.begin(), ans.end());
 
        // Print the string
        cout << ans;
    }
}
 
// Driver Code
int main()
{
    string S = "toffee";
    int K = 4;
    findString(S, K);
 
    return 0;
}


Java
// Java code for above approach
import java.util.*;
 
class GFG{
 
// Function to find the minimum number
// of string required to generate
// the original string
static void findString(String S, int N)
{
   
    // Stores the frequency of each
    // character of string S
    int[] amounts = new int[26];
 
    // Iterate over the range [0, 25]
    for (int i = 0; i < 26; i++) {
        amounts[i] = 0;
    }
 
    // Stores the frequency of each
    // character of string S
    for (int i = 0; i < S.length(); i++) {
        amounts[(int)(S.charAt(i) - 97)]++;
    }
 
    int count = 0;
 
    // Count unique characters in S
    for (int i = 0; i < 26; i++) {
        if (amounts[i] > 0)
            count++;
    }
 
    // If unique characters is greater
    // then N, then return -1
    if (count > N) {
        System.out.print("-1");
    }
 
    // Otherwise
    else {
 
        String ans = "";
        int high = 100001;
        int low = 0;
        int mid, total;
 
        // Perform Binary Search
        while ((high - low) > 1) {
 
            total = 0;
 
            // Find the value of mid
            mid = (high + low) / 2;
 
            // Iterate over the range
            // [0, 26]
            for (int i = 0; i < 26; i++) {
 
                // If the amount[i] is
                // greater than 0
                if (amounts[i] > 0) {
                    total += (amounts[i] - 1)
                                 / mid
                             + 1;
                }
            }
 
            // Update the ranges
            if (total <= N) {
                high = mid;
            }
            else {
                low = mid;
            }
        }
 
        System.out.print(high + " ");
 
        total = 0;
 
        // Find the resultant string
        for (int i = 0; i < 26; i++) {
 
            if (amounts[i] > 0) {
                total += (amounts[i] - 1)
                             / high
                         + 1;
 
                for (int j = 0;
                     j < ((amounts[i] - 1)
                              / high
                          + 1);
                     j++) {
 
                    // Generate the subsequence
                    ans += (char)(i + 97);
                }
            }
        }
 
        // If the length of resultant
        // string is less than N than
        // add a character 'a'
        for (int i = total; i < N; i++) {
            ans += 'a';
        }
         
        String reverse = "";
        int Len = ans.length() - 1; 
            while(Len >= 0) 
            { 
                reverse = reverse + ans.charAt(Len); 
                Len--; 
            }
 
        // Print the string
        System.out.print(reverse);
    }
}
 
// Driver Code
public static void main(String[] args)
{
    String S = "toffee";
    int K = 4;
    findString(S, K);
}
}
 
// This code is contributed by target_2.


Python3
# Python3 program for the above approach
 
# Function to find the minimum number
# of string required to generate
# the original string
def findString(S, N):
     
    # Stores the frequency of each
    # character of String S
    amounts = [0] * 26
     
    # Stores the frequency of each
    # character of String S
    for i in range(len(S)):
        amounts[ord(S[i]) - 97] += 1
         
    count = 0
     
    # Count unique characters in S
    for i in range(26):
        if amounts[i] > 0:
            count += 1
             
    # If unique characters is greater
    # then N, then return -1
    if count > N:
        print("-1")
         
    # Otherwise
    else:
        ans = ""
        high = 100001
        low = 0
         
        # Perform Binary Search
        while (high - low) > 1:
            total = 0
             
            # Find the value of mid
            mid = (high + low) // 2
             
            # Iterate over the range
            # [0, 26]
            for i in range(26):
                 
                # If the amount[i] is
                # greater than 0
                if amounts[i] > 0:
                    total += (amounts[i] - 1) // mid + 1
                     
            # Update the ranges
            if total <= N:
                high = mid
            else:
                low = mid
                 
        print(high, end = " ")
        total = 0
         
        # Find the resultant string
        for i in range(26):
            if amounts[i] > 0:
                total += (amounts[i] - 1) // high + 1
                for j in range((amounts[i] - 1) // high + 1):
                    ans += chr(i + 97)
         
        # If the length of resultant
        # string is less than N than
        # add a character 'a'            
        for i in range(total, N):
            ans += 'a'
             
        ans = ans[::-1]
         
        # Print the string
        print(ans)
 
# Driver code
S = "toffee"
K = 4
 
findString(S, K)
 
# This code is contributed by Parth Manchanda


C#
// C# program for the above approach
using System;
 
class GFG{
     
// Function to find the minimum number
// of string required to generate
// the original string
static void findString(string S, int N)
{
   
    // Stores the frequency of each
    // character of string S
    int[] amounts = new int[26];
 
    // Iterate over the range [0, 25]
    for (int i = 0; i < 26; i++) {
        amounts[i] = 0;
    }
 
    // Stores the frequency of each
    // character of string S
    for (int i = 0; i < S.Length; i++) {
        amounts[(int)(S[i] - 97)]++;
    }
 
    int count = 0;
 
    // Count unique characters in S
    for (int i = 0; i < 26; i++) {
        if (amounts[i] > 0)
            count++;
    }
 
    // If unique characters is greater
    // then N, then return -1
    if (count > N) {
        Console.Write("-1");
    }
 
    // Otherwise
    else {
 
        string ans = "";
        int high = 100001;
        int low = 0;
        int mid, total;
 
        // Perform Binary Search
        while ((high - low) > 1) {
 
            total = 0;
 
            // Find the value of mid
            mid = (high + low) / 2;
 
            // Iterate over the range
            // [0, 26]
            for (int i = 0; i < 26; i++) {
 
                // If the amount[i] is
                // greater than 0
                if (amounts[i] > 0) {
                    total += (amounts[i] - 1)
                                 / mid
                             + 1;
                }
            }
 
            // Update the ranges
            if (total <= N) {
                high = mid;
            }
            else {
                low = mid;
            }
        }
 
        Console.Write(high + " ");
 
        total = 0;
 
        // Find the resultant string
        for (int i = 0; i < 26; i++) {
 
            if (amounts[i] > 0) {
                total += (amounts[i] - 1)
                             / high
                         + 1;
 
                for (int j = 0;
                     j < ((amounts[i] - 1)
                              / high
                          + 1);
                     j++) {
 
                    // Generate the subsequence
                    ans += (char)(i + 97);
                }
            }
        }
 
        // If the length of resultant
        // string is less than N than
        // add a character 'a'
        for (int i = total; i < N; i++) {
            ans += 'a';
        }
         
        string reverse = "";
        int Len = ans.Length - 1; 
            while(Len >= 0) 
            { 
                reverse = reverse + ans[Len]; 
                Len--; 
            }
 
        // Print the string
        Console.Write(reverse);
    }
}
 
// Driver Code
public static void Main()
{
    string S = "toffee";
    int K = 4;
    findString(S, K);
}
}
 
// This code is contributed by splevel62.


Javascript


输出:
2 tofe

时间复杂度: O(N)
辅助空间: O(1)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程