📜  解决密码谜题 | 2套

📅  最后修改于: 2021-10-28 01:45:01             🧑  作者: Mango

给定一个字符串数组,大小为N 的arr[]和一个字符串S ,任务是寻找是否可以将范围[0, 9]中的整数值映射到字符串中出现的每个字母表,使得将数组中所有字符串编码形成的数字相加后得到的和等于字符串S形成的数字。

例子:

此处讨论了本文的第1组,其中字符串数组的大小为2

方法:给定的问题可以使用回溯解决。请按照以下步骤解决问题:

  • 初始化三个,数组表示mp[26]、 Hash[26]CharAtfront[26]来存储字母表的映射值、每个字符串中一个字母表的位置值的总和,以及如果一个字符在开头任何字符串的索引。
  • 初始化一个数组used[10]来存储一个数字是否映射到任何字母表。
  • 初始化一个 StringBuffer 说unique以将每个出现的字母表存储一次的字符串。
  • -1分配给mp 的每个数组元素。
  • 使用变量i遍历数组arr[]并执行以下操作:
    • 将字符串的长度arr[i] 存储在变量M 中
    • 使用变量j遍历字符串arr[i]并执行以下操作:
      • 如果mp[arr[i][j] – ‘A’]-1 ,则在uniq 中附加arr[i][j]并将0分配给mp[arr[i][j]-‘A]
      • 现在将Hash[arr[i][j] -‘A’] 的值增加10 (Mj-1)
      • 如果arr[i].length() > 1j0,则在arr[i][j] – CharAtfront[] 中的‘A’处标记为真。
  • 遍历字符串S并执行与对每个数组字符串执行的任务相同的任务。
  • -1填充到mp 的每个数组元素
  • 定义一个递归函数say solve(String word, int i, int S, int[] mp, int[] used)用于回溯:
    • 如果i等于word.length()则返回true如果S0 。否则,返回false
    • 如果mp[word[i]-‘A’]不等于-1然后递归 称呼 函数solve(word, i+1, S+mp[word[i]-‘A’]*Hash[word[i]-‘A], mp, used)然后返回它返回的值。
    • 否则,将变量X初始化为false并使用变量j在范围[0, 9] 上迭代并执行以下操作:
      • 如果满足任何条件,则继续循环中的下一次迭代:
        • 如果used[j]true
        • 如果CharAtfront[word[i]-‘A’]1并且j0
      • 现在将used[j]标记为true并将j分配给mp[word[i]-‘A’]。
      • 上述步骤后调用函数solve(word, i+1, S + j * Hash[word[i]-‘A’], mp, used) ,然后将X与其返回的值进行按位或运算。
      • 现在将used[j]标记为false并将-1分配给mp[word[i] – ‘A’]以进行回溯。
    • 返回X的值。
  • 最后,完成上述步骤后,如果solve(uniq, 0, 0, mp, used)返回的值为true,然后打印“”。否则,打印“”。

下面是上述方法的实现:

Java
// Java program for the above approach
import java.io.*;
import java.util.*;
  
class GFG {
  
    // Function to check if the
    // assignment of digits to
    // chacracters is possible
    public static boolean isSolvable(String[] words,
                                     String result)
    {
        // Stores the value
        // assigned to alphabets
        int mp[] = new int[26];
  
        // Stores if a number
        // is assigned to any
        // character or not
        int used[] = new int[10];
  
        // Stores the sum of position
        // value of a character
        // in every string
        int Hash[] = new int[26];
  
        // Stores if a character
        // is at index 0 of any
        // string
        int CharAtfront[] = new int[26];
  
        Arrays.fill(mp, -1);
        Arrays.fill(used, 0);
        Arrays.fill(Hash, 0);
        Arrays.fill(CharAtfront, 0);
  
        // Stores the string formed
        // by concatanating every
        // occured character only
        // once
        StringBuilder uniq = new StringBuilder();
  
        // Iterater over the array,
        // words
        for (String word : words) {
  
            // Iterate over the string,
            // word
            for (int i = 0; i < word.length(); i++) {
  
                // Stores the character
                // at ith position
                char ch = word.charAt(i);
  
                // Update Hash[ch-'A]
                Hash[ch - 'A'] += (int)Math.pow(
                    10, word.length() - i - 1);
  
                // If mp[ch-'A'] is -1
                if (mp[ch - 'A'] == -1) {
  
                    mp[ch - 'A'] = 0;
                    uniq.append((char)ch);
                }
  
                // If i is 0 and word
                // length is greater
                // than 1
                if (i == 0 && word.length() > 1) {
  
                    CharAtfront[ch - 'A'] = 1;
                }
            }
        }
  
        // Iterate over the string result
        for (int i = 0; i < result.length(); i++) {
  
            char ch = result.charAt(i);
  
            Hash[ch - 'A'] -= (int)Math.pow(
                10, result.length() - i - 1);
  
            // If mp[ch-'A] is -1
            if (mp[ch - 'A'] == -1) {
                mp[ch - 'A'] = 0;
                uniq.append((char)ch);
            }
  
            // If i is 0 and length of
            // result is greater than 1
            if (i == 0 && result.length() > 1) {
                CharAtfront[ch - 'A'] = 1;
            }
        }
  
        Arrays.fill(mp, -1);
  
        // Recursive call of the function
        return solve(uniq, 0, 0, mp, used, Hash,
                     CharAtfront);
    }
  
    // Auxiliary Recursive function
    // to perform backtracking
    public static boolean solve(
        StringBuilder words, int i,
        int S, int[] mp, int[] used,
        int[] Hash,
        int[] CharAtfront)
    {
        // If i is word.length
        if (i == words.length())
  
            // Return true if S is 0
            return (S == 0);
  
        // Stores the character at
        // index i
        char ch = words.charAt(i);
  
        // Stores the mapped value
        // of ch
        int val = mp[words.charAt(i) - 'A'];
  
        // If val is -1
        if (val != -1) {
  
            // Recursion
            return solve(words, i + 1,
                         S + val * Hash[ch - 'A'],
                         mp, used,
                         Hash, CharAtfront);
        }
  
        // Stores if there is any
        // possible solution
        boolean x = false;
  
        // Iterate over the range
        for (int l = 0; l < 10; l++) {
  
            // If CharAtfront[ch-'A']
            // is true and l is 0
            if (CharAtfront[ch - 'A'] == 1
                && l == 0)
                continue;
  
            // If used[l] is true
            if (used[l] == 1)
                continue;
  
            // Assign l to ch
            mp[ch - 'A'] = l;
  
            // Marked l as used
            used[l] = 1;
  
            // Recursive function call
            x |= solve(words, i + 1,
                       S + l * Hash[ch - 'A'],
                       mp, used, Hash, CharAtfront);
  
            // Backtrack
            mp[ch - 'A'] = -1;
  
            // Unset used[l]
            used[l] = 0;
        }
  
        // Return the value of x;
        return x;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        // Input
        String[] arr
            = { "SIX", "SEVEN", "SEVEN" };
        String S = "TWENTY";
  
        // Function Call
        if (isSolvable(arr, S))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}


输出
Yes

时间复杂度: O(N*M+10!),其中 M 是最大字符串的长度。
辅助空间: O(26)

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