将N划分成多个部分,每个部分的个数和大小都是2的幂,并且在JavaScript中限制部分大小和个数


我们需要编写一个JavaScript函数,该函数接收一个数字作为输入。该函数应根据以下规则将数字分成块:

  • 块的数量应为2的幂;

  • 每个块也应该有2的幂个元素(大小最大为2的幂,例如1, 2, 4, 8, 16, 32,最大值为32);

例如,8可以分成1个桶:

[8]

9可以分成:

[8, 1]

这是可行的,因为这两个数字都是2的幂,数组的大小也是2(也是2的幂)。

让我们尝试11:

[8, 2, 1]

不行,这不行。

因为数组的大小是3,它不是2的幂,即使它加起来是11。

[4, 4, 2, 1]

这个可以!它有4个元素,是2的幂。

示例

代码如下:

function permuteCombinations(n, maximum){
   const maxPowerOf2 = 1 << maximum;
   const m = ~~(n / maxPowerOf2);
   const A = new Array(maximum + 1).fill(0);
   A[maximum] = m;
   let num = n − m * maxPowerOf2;
   let p = 0;
   let bitCount = 0;
   while (num){
      if (num & 1){
         bitCount += 1;
         A[p] = 1;
      }
      num >>= 1;
      p += 1;
   }
   const min = m + bitCount;
   let target = 1;
   while (target < min)
   target *= 2;
   if (target > n)
   return −1;
   if (target == min)
   return A.map((c, p) => [1 << Number(p), c]);
   if (target == n)
   return [n];
   target = target − min;
   let i = m ? maximum : p;
   while (target && i > 0){
      if (!A[i]){
         i −= 1;
         continue;
      }
      const max = Math.min(target, A[i]);
      A[i] −= max;
      A[i−1] += 2*max;
      target −= max;
      i −= 1;
   }
   return target ? −1 : A.map((c, p) => [1 << Number(p), c]);
};
console.log(permuteCombinations(11, 5));

输出

控制台输出为:

[ [ 1, 1 ], [ 2, 1 ], [ 4, 2 ], [ 8, 0 ], [ 16, 0 ], [ 32, 0 ] ]

更新于:2020年11月21日

91 次浏览

启动您的职业生涯

完成课程后获得认证

开始
广告