leetcode 342

leetcode 342

题目

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?

Credits:
Special thanks to @yukuairoy for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

大意就是如何判断一个数字是不是4的k次幂。进阶版本是如何使用非循环的方法来实现。

本文只介绍如何使用非循环的方式来实现。废话不多说,上代码。

实现

    //leetcode 342
    bool isPowerOfFour(int num) {
        if(num <= 0)return false;
        bitset<32> bits(num);
        //判断是否为2的幂
        if(bits.count() != 1){return false;}
        else{
            //判断奇数位是否是1
            bits = num&0x55555555;
            return bits.count() == 1;
        }
    }

思路

首先小于等于0的数肯定不是4的幂,进行排除。
一个基本思路是首先判断这个数是不是2的幂,然后查看二进制下1的后面是否有偶数个0。
判断是否为2的幂的方法很简单,即查看二进制的数字是否存在且只存在1个1
eg:0000 0010
判断1后面是否存在偶数个0的方法为:num&0x55555555,即判断只有1个1,且其落在奇数位。
eg:0000 0010&0101 0101 = 0000 0000 ,0001 0000&0101 0101 = 0001 0000

拓展

bitset.count()的时间复杂度是什么呢?它会不会直接是一个循环的调用,导致我们写的这份代码只是一个想象中非常美好,却只是一坨X呢?
查看了一下OSX中的STL实现。

<bitset>
template <size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
size_t
bitset<_Size>::count() const _NOEXCEPT
{
    return static_cast<size_t>(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true));
}

<algorithm>
template <class _InputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
typename iterator_traits<_InputIterator>::difference_type
count(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
{
    typename iterator_traits<_InputIterator>::difference_type __r(0);
    for (; __first != __last; ++__first)
        if (*__first == __value_)
            ++__r;
    return __r;
}

可以看到,这里实现的方式其实是按照会循环执行32次。但是我们只是关注了代码,并未考虑编译器的优化和硬件指令集。
https://www.quora.com/What-is-complexity-of-the-count-function-in-C++-std-bitset,这篇参考文章中说部分硬件会使用精心设计的硬件结构来进行实现count。
例如x86的部分CPU设计了指令popcnt来使用。
http://stackoverflow.com/questions/34407437/what-is-the-efficient-way-to-count-set-bits-at-a-position-or-lower,介绍了不同的有效率的count实现方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值