可能的组合和转换为字母表算法-Javascript(Facebook要求)

可能的组合和转换为字母表算法-Javascript(Facebook要求),javascript,algorithm,combinations,alphabet,Javascript,Algorithm,Combinations,Alphabet,我正在为下一次面试学习算法,我发现了这个问题 这是Facebook提出的问题 问题出在这里 给定映射a=1,b=2。。。z=26,对于编码的消息,计算其解码方式的数量 例如,消息“111”将给出3,因为它可以被解码为“aaa”、“ka”和“ak” 我想我可以处理映射和转换为字母部分。但组合对我来说并不容易 考虑到我花了几个小时才写出下面的代码 function combinations(str) { var fn = function(active, rest, a) { // i

我正在为下一次面试学习算法,我发现了这个问题

这是Facebook提出的问题

问题出在这里


给定映射a=1,b=2。。。z=26,对于编码的消息,计算其解码方式的数量

例如,消息“111”将给出3,因为它可以被解码为“aaa”、“ka”和“ak”


我想我可以处理映射和转换为字母部分。但组合对我来说并不容易

考虑到我花了几个小时才写出下面的代码

function combinations(str) {
var fn = function(active, rest, a) {

    // if nothing, just return
    if (!active && !rest)
        return;


    // there is nothing left in rest add active to A
    if (rest.length == 0) {
        a.push(active);
    } else {

        // append first number of rest to the end of the active item
        // [1] + 1 => 111
        // [1,2] + [3,4] = [1,2,3] + [4]
        if (rest.length > 0){
            fn(active.concat(rest[0]), rest.slice(1), a);
        }else {}


        // join 

        fn((active+rest[0]).split(","), rest.slice(1), a);
    }
    return a;
  }
  return fn([], str, []);
}

// run it
combinations(1,2,3);
我只有这个

[ [ 1, 2, 3 ],
[ '1', '23' ],
[ '12', 3 ],
[ '123' ],
[ '1', 2, 3 ],
[ '1', '23' ],
[ '12', 3 ],
[ '123' ] ]
请参阅重复项。我想我现在可以除以2得到我想要的答案。但这并不是一个好答案

你能把它变成更好的代码吗

多谢各位



上面的代码几乎来自此

在本例中,我们不需要实际创建组合来计算它们。我们可以使用

f(i)
表示在字符串
S
中解码消息的有效方法的数量,最多包括索引
i
处的字符(以零为基础)。然后:

例如:

S = "123"

f(0) = 1
f(1) = f(0) + f(-1) = 2
f(2) = f(1) + f(0) = 3

这个过程的复杂性是
O(n)
时间和
O(1)
空间。

我把@•15006;עבקן的答案改成javascript,希望它不会破坏任何东西,我认为它正在工作

const Number = 11222;
let sum = 0;

const AlphabetGen = (i) => {

if(i == 0 ){
    sum =+ 1;
}else if ((Number[i] > 6) || (Number[i-1] > 3)){

    sum =+ AlphabetGen(i-1);
}else if(i > 0){
    if(i > 1){
        sum =+ AlphabetGen (i-1) + AlphabetGen(i-2);

    }else if (i == 1){
        sum =+ AlphabetGen (0) + 1
    }

}

return sum;
};

console.log(AlphabetGen(4));

我在JavaScript中使用简单的interator对此的看法:

let processString = ( message, possibleWays = 0 ) => {
  if ( message.length ) {
    // First decode using single digit.
    // Shorten string by one and process again.
    possibleWays = processString( message.slice( 1 ,message.length), possibleWays );

    // Then check if current digit can be combined
    // with the next digit for cases like '11' for J, '12' for K, etc.
    const numCurr = parseInt( message[0] );
    const numNext = "undefined" === typeof message[1] ? null : parseInt(message[1]);

    if ( numCurr && numNext
        && numCurr < 3 // first digit can't be more that 2 as 26 letter max.
        && ( numCurr + numNext ) < 27 // sum of two should be < 26 as 26 letter max.
    ) {
      // Shorten string by two and process again.
      possibleWays = processString( message.slice( 2 ,message.length), possibleWays );
    }
  } else {
    // Reached end of the string: + 1 possible way to decode it.
    possibleWays++;
  }

  return possibleWays;
}

console.log( 'Total number of decoding possbilities: ' + processString('12325') );
let processString=(消息,可能路径=0)=>{
if(message.length){
//首先使用一位数进行解码。
//将字符串缩短1,然后再次处理。
possibleWays=processString(message.slice(1,message.length),possibleWays);
//然后检查当前数字是否可以组合
//下一个数字表示“11”表示J,“12”表示K等情况。
const numCurr=parseInt(消息[0]);
const numNext=“undefined”==消息[1]的类型?null:parseInt(消息[1]);
如果(numCurr&&numNext
&&numCurr<3//第一个数字不能超过2,最多26个字母。
&&(numCurr+numNext)<27//两个字母之和应小于26,最大为26个字母。
) {
//将字符串缩短2,然后再次处理。
possibleWays=processString(message.slice(2,message.length),possibleWays);
}
}否则{
//到达字符串末尾:+1可能的解码方法。
可能途径++;
}
返回可能路径;
}
log('解码可能性总数:'+processString('12325');

如果是字符解码,你怎么能有
123
?因为OP是在寻找算法,而不是JS特定的实现,所以不应该考虑不同的语言(JS和Java在dupe中)。这是正确的@Rajesh这在其他语言中有一个解决这个问题的答案。(我只是更喜欢js,我就是这么做的。)如果你愿意,你可以查看下面答案的js版本。好主意。谢谢@我已经改成了下面的javascript版本。这是一个很好的答案,但我想知道为什么S[I-1]应该大于3?例如,“133”应该产生两个结果“13 3”和“1 3 3”,而不是3。是的,这是我已经证实是正确的。再次感谢您提供了一个很好的解决方案!您的答案不能编辑,但在这里:}else if((数字[i]>6)| |(数字[i-1]>3)){应该改为}else if((数字[i]>6)| |(数字[i-1]>2)){
let processString = ( message, possibleWays = 0 ) => {
  if ( message.length ) {
    // First decode using single digit.
    // Shorten string by one and process again.
    possibleWays = processString( message.slice( 1 ,message.length), possibleWays );

    // Then check if current digit can be combined
    // with the next digit for cases like '11' for J, '12' for K, etc.
    const numCurr = parseInt( message[0] );
    const numNext = "undefined" === typeof message[1] ? null : parseInt(message[1]);

    if ( numCurr && numNext
        && numCurr < 3 // first digit can't be more that 2 as 26 letter max.
        && ( numCurr + numNext ) < 27 // sum of two should be < 26 as 26 letter max.
    ) {
      // Shorten string by two and process again.
      possibleWays = processString( message.slice( 2 ,message.length), possibleWays );
    }
  } else {
    // Reached end of the string: + 1 possible way to decode it.
    possibleWays++;
  }

  return possibleWays;
}

console.log( 'Total number of decoding possbilities: ' + processString('12325') );