无需T9即可有效计算键盘序列可能单词的算法

时间:2018-12-18 11:08:36

标签: algorithm

免责声明:由于存在一些相似但没有相等的问题,请仔细阅读,我只能找到带有T9的键盘参考,但没有人没有。

  • 提供带有字母的电话键盘

2-a,b,c

3-d,e,f

...等等

  • 给出一个数字序列,例如222

请求:查找可以写多少个单词没有T9

示例:

222可以是:

for netobject in netObjectList:
    for key, value in netobject.getObjectParams().items():
        if checkForNotEmptyValue(key, value): 
            NValidator.checkSyntaxOfValue(key, value)

所以,有4种可能的解决方案

2222可以是:

array (size=4)
  0 => string 'C' (length=1)
  1 => string 'AB' (length=2)
  2 => string 'BA' (length=2)
  3 => string 'AAA' (length=3)

所以,有7种可能的解决方案

要求:
-没有回溯/暴力手段
-必须高效且序列较长(大于1000位,少于10秒才能执行)
-无需返回所有可能的单词,只需返回其计数

请注意:我不是在寻找最终的算法,而是要指出可能的方法

谢谢

1 个答案:

答案 0 :(得分:2)

enter image description here

算法/直觉:

  • 如上图所示,对于一位数字,存在3-4种可能性。
  • 如果我们按相同的数字2或3或4次,则显示的字符将不同。
  • 就像,如果我们按2
    • 1次-a
    • 2次-b
    • 3次-c
  • 因此,当我们计算/计算可能的子字符串数时,如果发生subproblem(i-2),subproblem(i-3),subproblem(i-4),我们需要将i = i-1 = i-2值添加到总数中。
  • 例如,以 222 为例。我们将采用自上而下的方法。
  • 222 中的第一个 2 只有一种可能性(将输入a)。
  • 222 中的第二个 2 中,它可以给我们a,也可以按两次2给我们一个b。因此,组合可以是aab
  • 对于 222 中的第三个 2 ,它可以是ab(如果从第二个2开始)或{ {1}}。
  • 因此,不。每个索引c的组合的总和为no。从iii-3的匹配项,具体取决于编号。键盘上每个数字代表的字符数。
  • 请注意,如果第i个 字符与i-4匹配,则我们添加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));
        }
    }
}