【问题标题】:Possible combinations and convert into alphabet algorithm - Javascript (asked by Facebook)可能的组合并转换为字母算法 - Javascript(由 Facebook 询问)
【发布时间】:2018-01-10 04:37:54
【问题描述】:

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

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 并得到我想要的答案。仍然不是一个很好的答案。

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

谢谢


上面的代码几乎来自这个link

【问题讨论】:

  • 如果它的字符解码,你怎么会有123
  • 由于 OP 正在寻找算法而不是 JS 特定的实现,因此不应考虑不同的语言(JS vs Java in dupe)。
  • 没错@Rajesh 这个post 有其他语言的这个问题的答案。 (我只是更喜欢js,这就是我的工作。)如果你愿意,你可以查看下面答案的js版本。

标签: javascript algorithm combinations alphabet


【解决方案1】:

在这种情况下,我们不需要实际创建组合来计算它们。我们可以使用dynamic programming

f(i) 表示在字符串S 中解码消息的有效方法数,直到并包括索引i 处的字符(从零开始)。那么:

f(0)  = 1
f(i)  =
   if S[i] > 6 or S[i-1] > 2:
     // Nothing changes, we just
     // added a letter
     f(i-1)

   else:
     // All the ways to decode
     // up to (i-1) plus all the
     // ways to decode up to (i-2)
     // (let f(-1) equal 1)
     f(i-1) + f(i-2)

例子:

S = "123"

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

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

【讨论】:

  • 好主意。谢谢! @גלעד ברקן,我已更改为下面的 javascript 版本。
  • 这是一个很好的答案,但我想知道为什么 S[i-1] 应该大于 3?例如,“133”应该产生 2 个结果“13 3”和“1 3 3”,而不是 3。
  • 是的,这就是我验证的正确性。再次感谢@גלעדברקן 的好解决方案!
【解决方案2】:

我将@גלעד ברקן 答案更改为 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));

【讨论】:

  • 您的答案无法编辑,但在这里:}else if ((Number[i] > 6) || (Number[i-1] > 3)){ 应该改为 }else if (( Number[i] > 6) || (Number[i-1] > 2)){
【解决方案3】:

我在 JavaScript 中使用简单的交互器对此的看法:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2022-12-06
    • 2023-03-24
    • 1970-01-01
    • 2018-03-15
    • 2022-11-29
    • 1970-01-01
    相关资源
    最近更新 更多