【问题标题】:Count all possible strings from given mobile numeric keypad sequence从给定的移动数字键盘序列中计算所有可能的字符串
【发布时间】:2018-11-19 11:28:34
【问题描述】:

如何计算可以由给定数字序列(从 2 到 9)形成的所有可能字符串,其中每个数字代表一个移动按钮并映射到 3/4 字母表。例如:- 2 映射到 A,B,C,通过按按钮 2 三次“222”,可以形成的可能字符串是 {"AAA","AB","BA","C"}。 输入=“2233”,可能的字符串={“AADD”,“AAE”,“BDD”,“BE”}。

我需要一个伪代码来实现上述问题。

【问题讨论】:

  • 到目前为止,YOU 尝试过什么?向我们展示您的代码。你被卡住了吗?
  • 我没有代码,我需要知道如何操作。可能它可以通过递归解决方案通过计算数字的连续出现并寻找可以形成的可能的刺来解决,但这将花费太多时间。寻找 dp 解决方案

标签: algorithm dynamic-programming


【解决方案1】:

算法/直觉:

  • 如上图所示,对于单个数字,有 3-4 种可能性。
  • 如果我们按同一个数字 2、3 或 4 次,我们会在显示屏上看到不同的字符。
  • 喜欢,如果我们按2
    • 1 次 - a
    • 2 次 - b
    • 3 次 - c
  • 因此,当我们计算/计算可能的子字符串数量时,如果发生i = i-1 = i-2,我们需要将subproblem(i-2),subproblem(i-3),subproblem(i-4) 值添加到我们的总数中。
  • 例如,我们以 222 为例。我们将采用自上而下的方法。
  • 222 中的第一个 2 仅有 1 种可能性(将输入 a)。
  • 对于222中的第二个2,它可以给我们a,或者可能是2被按下了2次给我们一个b。所以,组合可以是aab
  • 对于222中的第三个2,可以是ab(如果从第二个2开始)或c
  • 因此,没有。每个索引i 的组合数是 no 的总和。从ii-3i-4 的匹配数,取决于编号。每个数字在键盘中代表的字符数。
  • 请注意,如果第 ith 个字符与 i-1 匹配,则我们添加 dp[i-2] 而不是 dp[i-1],因为 i-1 till i 表示单个字符(多次按下时)。李>

代码:

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));
        }
    }
}

输出:

222 : 4
2233 : 4
23456789 : 1
54667877 : 8
5466 : 2
7777 : 8
22 : 2
7898989899 : 26
77779999 : 64

【讨论】:

    【解决方案2】:

    不知道为什么我的编辑被拒绝,但只是想在 Vivek 的回答中编辑一件事。

    if(s.charAt(i) == s.charAt(j)){} 后面的 else 语句中会有 break 条件,否则会不必要地继续,即使字符不匹配。

    例如对于输入7898989899,输出应该是2,因为只有两种可能性,因为他的答案代码返回26,这是错误的。

    【讨论】:

      【解决方案3】:

      我们可以使用递归来解决这个问题。这个想法是逐个考虑每个输入数字,用移动键盘中的每个字符替换该数字,并为下一个数字重复出现。处理完所有数字后,我们打印结果。

          // 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;
      }
      

      【讨论】:

        猜你喜欢
        • 2013-03-21
        • 1970-01-01
        • 2022-12-07
        • 1970-01-01
        • 1970-01-01
        • 2015-10-07
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        相关资源
        最近更新 更多