华为面试:判断2的n次方

大家好,我是涛哥。

今天,我们来看华为的一道面试题目:如何判断一个整数是否为2的n次方,其中n为非数整数,要求效率尽可能高。

这是一道非常典型的面试题目,它有很多发散的形式,比如:如果把上述的2换成3、4、5,该怎么做才能高效呢?

接下来,我们从不同的角度分析,并给出上述所有情况的算法思路和代码验证,希望大家有所收获,顺便通过面试。

                         涛哥在华为松山湖闲逛所拍 

判断2的n次方

2的n次方的判断,是一个比较常见的问题。容易看出,2的n次方的二进制中,有且仅有一个1,  所以,可用如下思路来判断:


package main

import "fmt"

func is2Pow(n uint32) bool {
    if n == 0 {
        return false
    }
    
    if n & (n - 1) == 0 {
        return true
    }
    
    return false
}

func main() {
    for i := uint32(0); i < 100; i++ {
        if is2Pow(i) {
            fmt.Println(i)
        }
    }
}

判断3的n次方

因为3是质数,所以可以先找出32位正整数中3的n次方的最大值(即3486784401),然后,思路就很自然了,如下:


package main

import "fmt"

func is3Pow(n uint32) bool {
    if n == 0 {
        return false
    }
    
    if 3486784401 % n == 0 {
        return true
    }
    
    return false
}

func main() {
    for i := uint32(0); i < 100; i++ {
        if is3Pow(i) {
            fmt.Println(i)
        }
    }
}

判断4的n次方

4的n次方,首先必须是2的n次方,且有4^n = (3+1)^n, 根据二项式定理可知:4^n % 3 = 1,  所以,算法代码如下:      


package main

import "fmt"

func is4Pow(n uint32) bool {
    if n == 0 {
        return false
    }
    
    if n & (n - 1) != 0 {
        return false
    }
    
    if n % 3 == 1 {
        return true
    }
    
    return false
}

func main() {
    for i := uint32(0); i < 100; i++ {
        if is4Pow(i) {
            fmt.Println(i)
        }
    }
}

判断5的n次方

既然前面的方法都用了,那现在可考虑使用通用的方法了,如下:


package main

import "fmt"

func is5Pow(n uint32) bool {
    if n == 0 {
        return false
    }
  
  if n == 1 {
  return true
  }
    
  for {
    if n % 5 != 0 {
      return false
    }

    n = n / 5
    if n < 5 {
      break
    }
  }

  if n == 1 {
    return true
  }

  return false
}

func main() {
    for i := uint32(0); i < 100; i++ {
        if is5Pow(i) {
            fmt.Println(i)
        }
    }
}

整体来看,上述四种方法各有技巧,希望大家从中举一反三,揣摩到算法优化的思路,横扫类似的笔试面试问题,拿到满意的offer,也欢迎大家在评论区讨论交流。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值