LCP342 LeetCode 342. Power of Four

前言

来写个简单的题目。
位运算

题目

Acceptance : 34.11% Difficulty : Easy

Given an integer (singed 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 ?

Tags : Bit Manipulation

题解

题目很简单。如果用循环或者递归的话,只需要看它不断地除以4,最终会不会等于1,且全过程都能被整除。

找找规律的话,4, 16, 64, 256,看到这些4的倍数的数字的二进制数都只有一个1。这是有道理的,是4的power,则必是2的power。则必只有一个1。

再联想到之前的一个计算二进制数中1的个数(汉明码问题)的题目,那么用

while(num)
{
    num &= (num-1);
    cnt++;
}

就能计算出num中1的个数cnt。然而,有必要吗?
当然没有。我们只需要判断 if (num & (num -1))即可。若为真,则说明num中必含一个以上的1。若为0,则它只含有一个1。

再找找规律,拿calc.exe计算一下4 + 16 + 64 +…. 并使之处于程序员模式下的十六进制模式下。我们会发现,每次加法运算的结果的二进制数都是01010101这样婶儿的。那么,我们是不是可以用0x5555 5554来作为mask判断那个仅有的1Bit是不是在合适的位置上。

当然,这也是有道理的。2的power都只有一个1。且随指数增长,1在二进制数中依次左移1位。那么4的power应是依次左移2位。就会出现100,10 000, 10 00 000这样的power of 4。那么他们的和自然就是0101010101这样婶儿的了。

于是便有了非常简单的代码。然而Submit后WA,0没有被考虑到。修改后再Submit,WA,1也没有被考虑到。

后来把1考虑进入规律中,即成了1 + 4 + 16 + 64….,mask 可以用 0x5555 5555。

于是有了3个if语句4ms的Solution

class Solution {
public:
    bool isPowerOfFour(int num) {
        int mask = 0x55555555;
        if (num == 0)
            return false;
        if (num & (num - 1))
            return false;
        if (num & (~mask))
            return false;
        else
            return true;
    }
};

还可以再省略下吗?

看了眼Discussion中的大牛的代码。于是便有了下面的代码:

class Solution {
public:
    bool isPowerOfFour(int num) {
        if (num & (num - 1))
            return false;
        if (num & 0x55555555)
            return true;
        return false;
    }
};

然而这代码需要8ms来完成。
WHY!!!!
比起4ms的代码,这段代码只有精简,没有啰嗦啊。唯一一处就是当test case = 0的时候,这套代码需要运行一次减法,两次与。两个if。而4ms的代码只需要一次if就return了。
但是,当test cases != 0的时候,8ms的代码会少一次if判断啊。而且,使用0x5555 5555 直接&,而不是放入变量中(或者还有取非操作),应该会使编译出来的机器码更少更快速吧。
然而结果并非如此呢?这是为什么?

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深海Enoch

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值