We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
2749. Minimum Operations to Make the Integer Zero O(1) Time || [C++/JAVA/Python] Beginner-friendly || Bit Manipulation Linear Search On Answer (ft. Bit Count)
我觉得这道题目是最难的一道Q2的题目了。
比赛中我百思不得其解,我看到2的次方,就联想到了位运算,但每次操作都有一个num2阻拦,会影响到最后的位数,所以我就一直没明白如何解决。
我这里试图反推,从别人的solution中一步步模拟别人的思路,看能不能从中给我启发,能给我学到什么。
第一步,首先尽可能界定下边界范围。上面都说了比较看重位运算,不妨把这部分提出来,公式变成num1 - k * num2 = 2^i1 + 2^i2 + ... + 2 ^ ik。已知范围有num1、num2和i,右边是肯定大于0的,k也至少大于等于0,所以num2不能超过num1。
num1 - k * num2 = 2^i1 + 2^i2 + ... + 2 ^ ik
第二步,最难的一点——能不能确定答案的范围呢?假设有答案满足(不是-1),答案的上限是什么(下限肯定是0)? 还是回到公式num1 - k * num2,其等于2^i1 + 2^i2 + ... + 2 ^ ik,关注这个很特殊的二进制表示数。我们从已知出发,已知num1、num2,知道右边公式是一个long类型的数,求k。那么可以发现,其实方程num1 - k * num2是一个线性函数,只有两种图形,k是变量。所以k是单调变化的,递增/递减。然后关注右边式子,可以发现要满足有个k使得k个i,k 最大等于该数(可以分解成每个1),所以范围是(long)k <= (long)num1 - (long)k * num2,注意要转成long。如此就可以从小到大枚举k。
num1 - k * num2
2^i1 + 2^i2 + ... + 2 ^ ik
(long)k <= (long)num1 - (long)k * num2
第三步,从第一步的公式可知,结合第二步得到的答案的范围,既然是肯定了上限,那就遍历所有可能的答案,算出差值long diff = (long) num1 - (long) k * (long) num2,然后看k到底能不能满足构造2^i1 + 2^i2 + ... + 2 ^ ik。怎么看满不满足呢?从i的范围出发,[0, 60],所以最小时k是等于该数的位数个数之和,也就是得到判断条件bits <= k。
long diff = (long) num1 - (long) k * (long) num2
bits <= k
代码如下:
class Solution { public int makeTheIntegerZero(int num1, int num2) { if (num2 > num1) { return -1; } for (int k = 0; (long)k <= (long)num1 - (long)k * num2; k++) { long diff = (long) num1 - (long) k * (long) num2; long bits = Long.bitCount(diff); if (bits <= k) { return k; } } return -1; } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
2749. Minimum Operations to Make the Integer Zero
2749. Minimum Operations to Make the Integer Zero
O(1) Time || [C++/JAVA/Python] Beginner-friendly || Bit Manipulation
Linear Search On Answer (ft. Bit Count)
我觉得这道题目是最难的一道Q2的题目了。
比赛中我百思不得其解,我看到2的次方,就联想到了位运算,但每次操作都有一个num2阻拦,会影响到最后的位数,所以我就一直没明白如何解决。
我这里试图反推,从别人的solution中一步步模拟别人的思路,看能不能从中给我启发,能给我学到什么。
第一步,首先尽可能界定下边界范围。上面都说了比较看重位运算,不妨把这部分提出来,公式变成
num1 - k * num2 = 2^i1 + 2^i2 + ... + 2 ^ ik
。已知范围有num1、num2和i,右边是肯定大于0的,k也至少大于等于0,所以num2不能超过num1。第二步,最难的一点——能不能确定答案的范围呢?假设有答案满足(不是-1),答案的上限是什么(下限肯定是0)? 还是回到公式
num1 - k * num2
,其等于2^i1 + 2^i2 + ... + 2 ^ ik
,关注这个很特殊的二进制表示数。我们从已知出发,已知num1、num2,知道右边公式是一个long类型的数,求k。那么可以发现,其实方程num1 - k * num2
是一个线性函数,只有两种图形,k是变量。所以k是单调变化的,递增/递减。然后关注右边式子,可以发现要满足有个k使得k个i,k 最大等于该数(可以分解成每个1),所以范围是(long)k <= (long)num1 - (long)k * num2
,注意要转成long。如此就可以从小到大枚举k。第三步,从第一步的公式可知,结合第二步得到的答案的范围,既然是肯定了上限,那就遍历所有可能的答案,算出差值
long diff = (long) num1 - (long) k * (long) num2
,然后看k到底能不能满足构造2^i1 + 2^i2 + ... + 2 ^ ik
。怎么看满不满足呢?从i的范围出发,[0, 60],所以最小时k是等于该数的位数个数之和,也就是得到判断条件bits <= k
。代码如下:
The text was updated successfully, but these errors were encountered: