漫画算法-学习笔记(21)

漫画算法-小灰的算法之旅(21)

1. 如何判断一个数是否为2的整数次幂

Q:实现一个方法,来判断一个正整数是否是2的整数次幂(如16是2的4次方,返回true;18不是2的整数次幂,则返回false).要求性能尽可能高。

方法一(暴力枚举)
思路:

利用一个整形变量,让它从1开始,不断乘以2,将每一次乘2的结果和目标整数进行比较。

创建一个中间变量temp,初始值为1。然后进入一个循环,每次循环都让temp和目标整数相比较,如果相等,则说明目标整数是2的整数次幂,如果不相等,则让temp增大一倍,继续循环并进行比较。当temp的值大于目标整数时,说明目标整数不是2的整数次幂。

例如:给出一个整数19,则存在

1 X 2=2;

2 X 2=4;

4 X 2=8;

8 X 2 =16;

16 X 2=32; 因为32>19,所以19不是2的整数次幂。

时间复杂度

如果目标整数的大小是n,则此方法的时间复杂度是O(logn)

代码实现

public static boolean isPowerOf2(int num){
  int temp=1;
  while(temp<=num){
    if(temp==num){
      return true;
    }
    temp=temp*2;
  }
  return false;
}

public static void main(String[] args){
  
  System.out.println(isPowerOf2(32));
  System.out.println(isPowerOf(19));
}
golang实现
func isPowerOf2V1(num int) bool {

	temp :=1
	for temp<=num {
		if temp==num {
			return true
		}
		temp=temp*2
	}
	return false
}

func main(){
  log.Println("暴力枚举法")
	log.Println(isPowerOf2V1(32))
	log.Println(isPowerOf2V1(19))
}
方法二(枚举&&移位)
思路

利用一个整型变量,让它从1开始不断的向左移位,因为移位的性能比乘法高很多。

时间复杂度

采用移位运算,确实有一定的优化,但是咩有改变该算法的时间复杂度因此依旧是O(logn).

代码实现

public static boolean isPowerOf2V2(int num){
  int temp=1;
  while(temp<=num){
    if(temp==num){
      return true;
    }
    temp=temp<<1;
  }
  return false;
}
golang实现
func isPowerOf2V2(num int) bool {
	temp :=1
	for temp<=num {
		if temp==num {
			return true
		}
		temp=temp<<1
	}
	return false
}
方法三(按位与运算)
思路

如果一个整数是2的整数次幂,那么当它转化成二进制时,只有最高位是1,其它位都是0。如下图

此时,如果将这些2的整数次幂都各自减1之后,会发现它们都二进制数字就全都变成1了。

因为我们知道0和1按位与运算都结果都是0。如果我们将原数值(2的整数次幂)和它减1的结果进行按位与运算,即(n&(n-1)).我们会发现两者的按位与运算结果必然为0。因此,如果一个整数不是2的整数次幂,那么(n&(n-1))的结果必定不为0。

时间复杂度

按位与运算的是时间复杂度位O(1)

代码实现
public static boolean isPowerOf2V3(int num){
  return (num&(num-1))==0;
}
golang实现
//按位与运算 巧解 n&(n-1)==0
func isPowerOf2V3(num int) bool {
	return (num&(num-1))==0

}

func main() {

	log.Println("按位与运算")
	log.Println(isPowerOf2V3(32))
	log.Println(isPowerOf2V3(19))
}

总结

巧妙的利用二进制的按位与运算实现算法求解。计算机基础不能丢啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值