如何 O(1) 判断一个数是不是 x 的幂 (x 有限大)
数据在 32 位整数范围内
2 的幂
231. 2 的幂 - 力扣(LeetCode)
给你一个整数
n
,请你判断该整数是否是 2 的幂次方。如果是,返回true
;否则,返回false
。如果存在一个整数
x
使得n == 2x
,则认为n
是 2 的幂次方。
Sol1 位运算
n & n − 1 = 0 , 那么 n 是 2 的整次幂 n \; \& \; n - 1 = 0, 那么 \,n\, 是 \,2\, 的整次幂 n&n−1=0,那么n是2的整次幂
假设 n 的二进制为 ( a 10000 ) 2 (a10000)_2 (a10000)2 , 其中 a 表示若干高位 0, 1 表示最低位的 1。
那么 n-1 的二进制为 ( a 01111 ) 2 (a01111)_2 (a01111)2 , 两者做与运算,得到 ( a 0000 ) 2 (a0000)_2 (a0000)2 。
也就是说,n & n-1 可以去掉最低位的 1.
而 2 x 2^x 2x 的二进制表示只有一个 1,即 :
class Solution {
public:bool isPowerOfTwo(int n) {return n > 0 && (n & (n - 1)) == 0;}
};
Sol2 位运算
n & − n = n , 那么 n 是 2 的整次幂 n \; \& \; -n = n, 那么 \,n\, 是 \,2\, 的整次幂 n&−n=n,那么n是2的整次幂
假设 n 的二进制为 ( a 10000 ) 2 (a10000)_2 (a10000)2 , 其中 a 表示若干高位 0, 1 表示最低位的 1。
那么 -n 的二进制, 将 n 的二进制每一位取反再加 1,为 ( a ‾ 10000 ) 2 (\overline{a}10000)_2 (a10000)2 , 两者做与运算,得到 ( 01000 ) 2 (01000)_2 (01000)2 。
也就是说,n & -n 可以得到最低位的1
而 2 x 2^x 2x 的二进制表示只有一个 1,即 : n & -n = n
这也是树状数组里面常用的 l o w b i t lowbit lowbit 操作
Sol3 算数基本定理
因为在 32 位整数范围内,这个范围内最大的 2 x 2^x 2x 是 2 30 = 1073741824 2^{30}=1073741824 230=1073741824 ,只要 n 是它的约数就行了。
class Solution {
private:static constexpr int BIG = 1 << 30;public:bool isPowerOfTwo(int n) {return n > 0 && BIG % n == 0;}
};
3 的幂
326. 3 的幂 - 力扣(LeetCode)
Sol1 试除法
我们不断地将 n 除以 3,直到 n=1。如果此过程中 n 无法被 3 整除,就说明 n 不是 3 的幂。
class Solution {
public:bool isPowerOfThree(int n) {while (n && n % 3 == 0) {n /= 3;}return n == 1;}
};
Sol2 算数基本定理
还是找最大的 3 x 3^x 3x , 由算数基本定理,他的约数只有 2 y 2^y 2y , 其中 0 ≤ y ≤ x 0\leq y\leq x 0≤y≤x
class Solution {
public:bool isPowerOfThree(int n) {return n > 0 && 1162261467 % n == 0;}
};
4 的幂
342. 4的幂 - 力扣(LeetCode)
Sol1 二进制中一的位置
4 的幂一定是 2 的幂,先判定 n & − n = n n\;\&\; -n = n n&−n=n ,保证 n 是 2 的幂,此时 n 的二进制表示中只有一个 1, 而且这个 1 一定出现在偶数位上。构造 λ \lambda λ , 使得其所有奇数位上都为 1,若 n & λ ≠ 0 n\;\&\; \lambda \neq 0 n&λ=0 , 那么说明 n 的二进制形式存在奇数位的 1 ,不合法 ;否则,合法。综上 :
class Solution {
public:bool isPowerOfFour(int n) {return n > 0 && ((n & -n) == n) && (n & 0xaaaaaaaa) == 0;}
};
Sol2 取模性质
a b m o d p = ( a m o d p ) ) b m o d p a^b \;mod \; p = (a\;mod\;p))^b \;mod\;p abmodp=(amodp))bmodp
那么 4 x m o d 3 = 1 x = 1 4^x\;mod\;3=1^x=1 4xmod3=1x=1
如果 n 是 2 的幂,而不是 4 的幂,那么 n = 2 × 4 x n=2\times 4^x n=2×4x , 即 n ≡ 2 ( m o d 3 ) n\equiv 2 \;(mod\; 3) n≡2(mod3)
class Solution {
public:bool isPowerOfFour(int n) {return n > 0 && (n & (n - 1)) == 0 && n % 3 == 1;}
};
任意数 x 的幂
运用处理 3 的幂中的 Sol1 试除法即可,实际复杂度是 l o g x ( n ) log_x(n) logx(n) 的
或者直接预处理出来数据范围内的所有符合条件的数也可以,是 l o g x ( I N T _ M A X ) log_x(INT\_MAX) logx(INT_MAX) 的