LCP342 LeetCode 342. Power of Four
2016-06-08 15:27
288 查看
前言
来写个简单的题目。位运算
题目
Acceptance : 34.11% Difficulty : EasyGiven 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 直接&,而不是放入变量中(或者还有取非操作),应该会使编译出来的机器码更少更快速吧。
然而结果并非如此呢?这是为什么?
相关文章推荐
- Appium入门示例(Java)
- angular通过路由实现跳转 resource加载数据
- Masonry介绍与使用实践:快速上手Autolayout
- Android 5.X 新特性详解(一)——主题、Palette、阴影、着色和裁剪
- JPA的事务配置
- C语言的fork函数在Linux中的进程操作及相关面试题讲解
- android6.0SDK中删除HttpClient的相关类的解决方法
- Javascript代码规范
- Mysql 数据库备份和还原方法
- mysql 自动备份导出到sql
- Android使用线程获取网络图片的方法
- 如何将二维码转换成base64码
- matlab中数据保存的相关指令
- MyEclipse运行项目的内存溢出问题解决方案:Java.lang.OutOfMemoryError: PermGen space
- 进程和线程的区别和联系
- php实现的太平洋时间和北京时间互转的自定义函数
- sar
- OpenBLAS编译和安装简介
- java split 特殊元字符 需加\\
- JDBC连接各种数据库的方法(经典)