📜  构建目标字符串所需的最少字数

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

构建目标字符串所需的最少字数

给定一个字符串数组,大小为Mwords[]和大小为N的字符串目标。任务是通过从单词集合中剪切单个字母并重新排列它们来找到拼出字符串目标所需的最小单词数,前提是每个单词有无限的供应量。如果不可能,打印-1。

例子:

方法:这个想法是使用回溯。请按照以下步骤解决问题:

  • 声明一个二维数组,比如countMap[][],其中countMap[i][j]存储第i字符串中第j字符的计数。
  • 声明一个数组charAvavilable[26],表示当前可用字符数。
  • 定义一个递归函数,它将当前索引i (最初为 0) 的字符串, target作为输入。
    • 如果当前计数大于总计数,则返回。此外,如果当前索引i等于N ,则更新总计数并返回。
    • 如果charAvailable[]中出现target[i]
      • 减少charAvailable[]中字符target[i]的出现次数。
      • 递归调用索引i+1 ,同时将计数更新 1。
      • 在函数调用后将字符target[i]的出现增加 1 以进行回溯。
    • 否则,迭代countMap[][]以查找target[i]的出现。如果找到,则通过将 count 更新 1 来递归调用该函数,并在函数调用之后执行回溯步骤。
  • 打印所需的最少字数。

下面是上述方法的实现:

C++
// C++ program of the above approach
#include 
using namespace std;
 
// countMap[][] to store
// count of characters
vector > countMap;
 
int cnt = INT_MAX;
 
// Function to get minimum number of
// stickers for a particular state
void count(int curCnt, int pos, vectorcharAvailable,
           string target, vector stickers)
{
     
    // If an optimal solution is
    // already there, return
    if (curCnt >= cnt)
        return;
 
    int m = stickers.size();
    int n = target.size();
 
    // If Target has been constructed
    // update cnt and return
    if (pos == n)
    {
        cnt = min(cnt, curCnt);
        return;
    }
 
    char c = target[pos];
 
    if (charAvailable > 0)
    {
         
        // Update charAvailable[]
        charAvailable--;
 
        // Recursizevely function call
        // for (pos + 1)
        count(curCnt, pos + 1, charAvailable,
              target, stickers);
 
        // Update charAvailable[]
        charAvailable++;
    }
    else
    {
        for(int i = 0; i < m; i++)
        {
            if (countMap[i] == 0)
                continue;
 
            // Update charAvailable[]
            for(int j = 0; j < 26; j++)
            {
                charAvailable[j] += countMap[i][j];
            }
 
            // Recursizeve Call
            count(curCnt + 1, pos, charAvailable,
                  target, stickers);
 
            // Update charAvailable[]
            for(int j = 0; j < 26; j++)
            {
                charAvailable[j] -= countMap[i][j];
            }
        }
    }
}
 
// Function to find the minimum
// number of stickers
int minStickers(vector stickers,
                string target)
{
     
    // Base Case
    if (target == "")
        return -1;
 
    if (target.size() == 0)
        return 0;
 
    if (stickers.size() == 0)
        return -1;
 
    int m = stickers.size();
    countMap.resize(m, vector(26, 0));
     
    // Fill the countMap Array
    for(int i = 0; i < stickers.size(); i++)
    {
        string s = stickers[i];
        for(char c : s)
        {
            countMap[i]++;
        }
    }
 
    // Recusizeve function call to get
    // minimum number of stickers
    vector temp(26);
    count(0, 0, temp, target, stickers);
 
    return cnt == INT_MAX ? -1 : cnt;
}
 
// Driver Code
int main()
{
     
    // Given Input
    vector str = {"with", "example", "science"};
    string target = "thehat";
 
    // Function Call
    int Result = minStickers(str, target);
 
    // Print the result
    cout << Result;
}
 
// This code is contributed by mohit kumar 29


Java
// Java program of the above approach
import java.io.*;
import java.util.*;
 
class Sol {
 
    // countMap[][] to store
    // count of characters
    int[][] countMap;
 
    int cnt = Integer.MAX_VALUE;
 
    // Function to find the minimum
    // number of stickers
    public int minStickers(String[] stickers
                           , String target)
    {
        // Base Case
        if (target == null)
            return -1;
 
        if (target.length() == 0)
            return 0;
 
        if (stickers == null || stickers.length == 0)
            return -1;
 
        int m = stickers.length;
        countMap = new int[m][26];
 
        // Fill the countMap Array
        for (int i = 0; i < stickers.length; i++) {
            String s = stickers[i];
            for (char c : s.toCharArray()) {
                countMap[i]++;
            }
        }
 
        // Recursive function call to get
        // minimum number of stickers
        count(0, 0, new int[26], target, stickers);
 
        return cnt == Integer.MAX_VALUE ? -1 : cnt;
    }
 
    // Function to get minimum number of
    // stickers for a particular state
    private void count(int curCnt, int pos,
                       int[] charAvailable, String target,
                       String[] stickers)
    {
        // If an optimal solution is
        // already there, return
        if (curCnt >= cnt)
            return;
 
        int m = stickers.length;
        int n = target.length();
 
        // If Target has been constructed
        // update cnt and return
        if (pos == n) {
            cnt = Math.min(cnt, curCnt);
            return;
        }
 
        char c = target.charAt(pos);
 
        if (charAvailable > 0) {
 
            // Update charAvailable[]
            charAvailable--;
 
            // Recursively function call
            // for (pos + 1)
            count(curCnt, pos + 1, charAvailable, target,
                  stickers);
 
            // Update charAvailable[]
            charAvailable++;
        }
        else {
            for (int i = 0; i < m; i++) {
 
                if (countMap[i] == 0)
                    continue;
 
                // Update charAvailable[]
                for (int j = 0; j < 26; j++) {
                    charAvailable[j] += countMap[i][j];
                }
 
                // Recursive Call
                count(curCnt + 1, pos, charAvailable,
                      target, stickers);
 
                // Update charAvailable[]
                for (int j = 0; j < 26; j++) {
                    charAvailable[j] -= countMap[i][j];
                }
            }
        }
    }
}
 
class GFG {
 
    // Driver Code
    public static void main(String[] args)
    {
        Sol st = new Sol();
 
        // Given Input
        String[] str = { "with", "example", "science" };
        String target = "thehat";
 
        // Function Call
        int Result = st.minStickers(str, target);
 
        // Print the result
        System.out.println(Result);
    }
}


输出:
3

时间复杂度: O(M*26*2 N )
辅助空间: O(M*26)