zoukankan      html  css  js  c++  java
  • leetcode-342-Power of Four

    题目描述:

    Given an integer (signed 32 bits), write a function to check whether it is a power of 4.

    Example:
    Given num = 16, return true. Given num = 5, return false.

    Follow up: Could you solve it without loops/recursion?

     

    要完成的函数:

    bool isPowerOfFour(int num) 

     

    说明:

    这道题目是“2的整数次幂”的升级版本。从前文leetcode-231-Power of Two可知,这道题目我们有两种方法去处理。

    1、传统方法:

    先处理边界条件,如果小于等于0那么肯定不是4的整数次幂。然后,判断能不能整除4,如果可以一直除下去,直到最后等于1。如果在整除的过程中不能再整除4了,那么必定不是4的整数次幂。

    代码如下:

        bool isPowerOfFour(int num) 
        {
            if(num<=0)
                return false;
            while(num!=1)
            {
                if(num%4==0)
                    num>>=2;
                else
                    return false;
            }
            return true;//num==1和num>1的情况都可以处理
        }

    时间复杂度O(logn),实测6ms,beats 78.26% of cpp submissions。

    2:、第一种位操作法:

    首先跟2的整数次幂一样,利用(num&(num-1))==0来判断是不是2的整数次幂,对这个判断条件感兴趣的同学可以先看一下前文

    利用这个条件,其实我们可以知道符合这个条件的num都是只有1位为1,其余位为0的数。(二进制表示)

    接着我们要判断出:

    0000 0001  是4的整数次幂

    0000 0100  是4的整数次幂

    0001 0000  是4的整数次幂

    0100 0000  是4的整数次幂

    0000 0010  不是

    0000 1000  不是

    0010 0000  不是

    1000 0000  不是

    我们要做的工作其实就是检测1有没有出现在奇数位上,比如第一位,第三位,第五位,第七位……

    所以我们可以使用模板:0101 0101,来跟num值相“与”,判断在奇数位上有没有出现1。(这种方法也是检测1有没有出现在某个位上的常用做法)

    而把上述模板扩展到32位,就是0x55555555。

    代码如下:

        bool isPowerOfFour(int num) 
         {
            return((num&(num-1))==0 && num>0 && (num&0x55555555)==num);
         }

    时间复杂度O(1),实测仍然是6ms……

    3、第二种位操作法:

    同样首先利用(num&(num-1))==0进行第一步判断。

    接着我们可以利用4的整数次幂num的一个特性,就是num-1的值都是3的整数倍。

    比如:

    num为  1,也就是 0000 0001,num-1为0,也就是0000 0000。

    num为  4,也就是0000 0100,num-1为3 ,也就是0000 0011。

    num为16,也就是0001 0000,num-1为15,也就是0000 1111。

    num为64,也就是0100 0000,num-1为63,也就是0011 1111。

    我们发现num-1的值,都是从num-1=3那里开始,11向左移动两位,然后再加上11,形成num-1=15。

    然后再左移两位,再加上11,形成num-1=63。

    3的整数次倍(最开始的num-1=3)向左移动两位,再加上11(二进制),形成的数必定是3的整数次倍。(数学归纳法可证)

    所以利用这个4的整数次幂拥有而二的整数次幂没有的性质,我们可以构造出如下代码:

    bool isPowerOfFour(int num) 
    {
            return (num>0 && ((num-1)&num)==0 && (num-1)%3==0;
    }

    时间复杂度仍然为O(1),实测依旧是6ms……

    4、不能实现的一种做法:

    由于4不是素数,所以前文中第三种做法——找一个最大的int型整数,接着判断能否整除num的做法,对于这道题是不可行的。

    我们找到的这个最大的int型整数,即4^15,本身也可以整除2,4^15不是只含有4这个因子。

  • 相关阅读:
    css文字选中效果
    使用HTML5来实现本地文件读取和写入
    web响应式图片的5种实现
    前端日志上报的新姿势“Beacon”
    lock文件_我们为什么需要 lock 文件
    本地电脑和远程电脑无法复制粘贴
    device supports x86 but apk only supports armeabi-v7a问题解决
    Android Studio中 安卓模拟器 联网
    Android Studio 配置Gradle
    Android连载1-自定义UI控件
  • 原文地址:https://www.cnblogs.com/chenjx85/p/8854898.html
Copyright © 2011-2022 走看看