问题
How to count all possible string that can be formed from a given sequence of digits(from 2-9) where each digit represents a mobile button and is mapped to 3/4 alphabet. eg:- 2 is mapped to A,B,C, by pressing the button 2 three times "222", possible strings that can be formed are {"AAA","AB","BA","C"}. input= "2233", possible strings={"AADD","AAE","BDD","BE"}.
I need a pseudo-code to implement the above problem.
回答1:
Algorithm/Intuition:
- As it represents in the above image, for a single digit, there are 3-4 possibilities.
- If we press the same digit 2 or 3 or 4 times, we get different characters on the display.
- Like, if we press
2- 1 time -
a - 2 times -
b - 3 times -
c
- 1 time -
- So, when we calculate/count the number of possible substrings, we need to add
subproblem(i-2),subproblem(i-3),subproblem(i-4)values to our total count if it happens thati = i-1 = i-2. - For example, let's take 222. We will adopt a top-bottom approach.
- First 2 in 222 has only 1 possibility(which will be typing
a). - For second 2 in 222, it can give us either
aor it might be that2was pressed 2 times giving us ab. So, combinations can beaaandb. - For third 2 in 222, it can be
aorb(if started from second2) orc. - Hence, no. of combinations for each index
iis sum of no. of matches fromitilli-3ori-4, depending upon no. of characters each digit represents in the keypad. - Note that if ith character matches with
i-1, then we adddp[i-2]and notdp[i-1]sincei-1 till irepresents a single character (when pressed multiple times).
Code:
import static java.lang.System.out;
public class Solution{
public static int possibleStringCount(String s){
int len = s.length();
int[] dp = new int[len];
dp[0] = 1;// possibility is 1 for a single character
for(int i=1;i<len;++i){
int possible_chars_length = numberOfRepresentedCharacters(s.charAt(i)-'0') - 1;// because current character itself counts as 1.
dp[i] = 0;
for(int j=i;j>=0;j--){
if(i - possible_chars_length > j) break;
if(s.charAt(i) == s.charAt(j)){
if(j-1 > -1){
dp[i] += dp[j-1];
}else{
dp[i] += 1;// if there are no combinations before it, then it represents a single character
}
}
}
}
return dp[len-1];
}
private static int numberOfRepresentedCharacters(int digit){
if(digit == 7 || digit == 9) return 4;
return 3;// it is assumed that digits are between 2-9 always
}
public static void main(String[] args) {
String[] tests = {
"222","2233","23456789","54667877","5466","7777","22","7898989899","77779999"
};
for(String testcase : tests){
out.println(testcase + " : " + possibleStringCount(testcase));
}
}
}
Output:
222 : 4
2233 : 4
23456789 : 1
54667877 : 8
5466 : 2
7777 : 8
22 : 2
7898989899 : 26
77779999 : 64
回答2:
Don't know why my edits are getting rejected but just wanted to edit one thing in the Vivek's answer.
There will be break condition in the else statement after if(s.charAt(i) == s.charAt(j)){} otherwise it will go on unnecessarily, even after not matching the character.
For example for input 7898989899 the output should be 2 because there are only two possibilities, where'as his answer's code is returning 26 which is wrong.
回答3:
We can use Recursion to solve this problem. The idea is to consider every input digit one by one, replace the digit with each character in the mobile keypad and recur for the next digit. When all the digits are processed, we print the result.
// Recursive function to find all possible combinations by replacing key's digits
// with characters of the corresponding list
void findCombinations(auto const &keypad, auto const &input,
string res, int index)
{
// if we have processed every digit of key, print result
if (index == -1) {
cout << res << " ";
return;
}
// stores current digit
int digit = input[index];
// size of the list corresponding to current digit
int len = keypad[digit].size();
// one by one replace the digit with each character in the
// corresponding list and recur for next digit
for (int i = 0; i < len; i++) {
findCombinations(keypad, input, keypad[digit][i] + res, index - 1);
}
}
// main function
int main()
{
vector<char> keypad[] =
{
{}, {}, // 0 and 1 digit don't have any characters associated
{ 'A', 'B', 'C' },
{ 'D', 'E', 'F' },
{ 'G', 'H', 'I' },
{ 'J', 'K', 'L' },
{ 'M', 'N', 'O' },
{ 'P', 'Q', 'R', 'S'},
{ 'T', 'U', 'V' },
{ 'W', 'X', 'Y', 'Z'}
};
int input[] = { 2, 2, 3, 3};
int n = sizeof(input)/sizeof(input[0]);
findCombinations(keypad, input, string(""), n - 1);
return 0;
}
来源:https://stackoverflow.com/questions/53373675/count-all-possible-strings-from-given-mobile-numeric-keypad-sequence