优化获取二进制字符串的所有子字符串

时间:2019-07-31 11:02:50

标签: javascript string binary substring bit

代码是将十进制数转换为二进制,生成二进制字符串的所有可能的子字符串,并计算每个子字符串中0和1的奇数,最后返回总数。运行此代码会在hackerrank等网站中出现超时错误。应该使用哪种方法来降低复杂性?我尝试将所有二进制数推送到数组中,然后分别对其进行迭代以避免0(n ^ 3)。但是,即使那样似乎也不起作用。应该在这里采用动态编程方法吗?

    function getAllSubstrings(str) {
  let result = [];
  let n = str.length
  let oddZeroCnt = 0;
  let oddOneCnt = 0;
  for (let i = 0; i < n; i++)
    for (let j = i + 1; j <= n; j++) {
      let substr = str.substring(i, j);
      let zeroSubStr = (substr.split("0").length - 1)
      let oneSubStr = (substr.split("1").length - 1)
      if (zeroSubStr % 2 === 1) {
        oddZeroCnt++
      }
      if (oneSubStr % 2 === 1) {
        oddOneCnt++
      }
    }
  return oddZeroCnt + " " + oddOneCnt;
}

function getOddCounts(decNum) {
  return getAllSubstrings((decNum >> BigInt(0)).toString(2))
}
let input = BigInt(17)
console.log(getOddCounts(input))

1 个答案:

答案 0 :(得分:0)

(1)您不需要字符串。您可以使用number & (1 << position)检查是否在数字的位置设置了位。

(2)您甚至不需要计算的几率。每个非奇数均为偶数,因此total = even + odd。如果您知道组合的总数和奇数值的数量,则可以轻松计算出偶数。

(3)您只需迭代两次(O(n²))。如果您看一下17的这些组合,从0开始:

  1     ≠> odd
  10    => odd
  100   => odd
  1000  => odd
  10001 ≠> even

然后您会看到直到出现1为止,组合都是偶数,然后直到出现另一个1为止,它们才是奇数。如果您跟踪上一个组合是偶数还是奇数,则只需查看当前位就可以轻松确定下一个组合是否是奇数:

  let odd = false, odds = 0;

  /*...*/
     if(number & (1 << position)) odd = !odd;
     if(odd)  odds += 1;