给定一个字符串数组,大小为N 的arr[]和一个字符串S ,任务是寻找是否可以将范围[0, 9]中的整数值映射到字符串中出现的每个字母表,使得将数组中所有字符串编码形成的数字相加后得到的和等于字符串S形成的数字。
例子:
Input: arr[][] = {“SEND”, “MORE”}, S = “MONEY”
Output: Yes
Explanation:
One of the possible ways is:
- Map the characters as the following, ‘S’→ 9, ‘E’→5, ‘N’→6, ‘D’→7, ‘M’→1, ‘O’→0, ‘R’→8, ‘Y’→2.
- Now, after encoding the strings “SEND”, “MORE”, and “MONEY”, modifies to 9567, 1085 and 10652 respectively.
- Thus, the sum of the values of “SEND” and “MORE” is equal to (9567+1085 = 10652), which is equal to the value of the string “MONEY”.
Therefore, print “Yes”.
Input: arr[][] = {“SIX”, “SEVEN”, “SEVEN”}, S = “TWENTY”
Output: Yes
Explanation:
One of the possible ways is:
- Map the characters as the following, ‘S’→ 6, ‘I’→5, ‘X’→0, ‘E’→8, ‘V’→7, ‘N’→2, ‘T’→1, ‘W’→’3’, ‘Y’→4.
- Now, after encoding the strings “SIX”, “SEVEN”, and “TWENTY”, modifies to 650, 68782 and 138214 respectively.
- Thus, the sum of the values of “SIX”, “SEVEN”, and “SEVEN” is equal to (650+ 68782+ 68782 = 138214), which is equal to the value of the string “TWENTY”.
Therefore, print “Yes”.
此处讨论了本文的第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() > 1且j为0,则在arr[i][j] – CharAtfront[] 中的‘A’处标记为真。
- 遍历字符串S ,并执行与对每个数组字符串执行的任务相同的任务。
- 将-1填充到mp 的每个数组元素。
- 定义一个递归函数say solve(String word, int i, int S, int[] mp, int[] used)用于回溯:
- 如果i等于word.length()则返回true如果S是0 。否则,返回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并且j是0 。
- 现在将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 现场工作专业课程和学生竞争性编程现场课程。