代码是将十进制数转换为二进制,生成二进制字符串的所有可能的子字符串,并计算每个子字符串中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))
答案 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;