LeetCode系列Easy【1】 Algorithms - Bit manipulation

来源:互联网 发布:图像融合算法 编辑:程序博客网 时间:2024/06/05 05:18
  • 2016.10.09启程。。

LeetCode 答案 Github 来源
其他参考:
http://www.cnblogs.com/grandyang/p/4606334.html

Algorithms


Bit Manipulation


190. Reverse Bits

Leetcode 题目链接
Reverse bits of a given 32 bits unsigned integer.

For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).

Follow up:
If this function is called many times, how would you optimize it?

# Time : O(logn) = O(32)# Space: O(1)## Reverse bits of a given 32 bits unsigned integer.## For example, given input 43261596 (represented in binary as# 00000010100101000001111010011100), return 964176192 (represented in binary# as 00111001011110000010100101000000).## Follow up:# If this function is called many times, how would you optimize it?#class Solution:    # @param n, an integer    # @return an integer    def reverseBits(self, n):        result = 0        for i in xrange(32):            result <<= 1            result |= n & 1            n >>= 1        return resultif __name__ == '__main__':  print Solution().reverseBits(1)

相关解答:
http://www.cnblogs.com/grandyang/p/4321355.html

知识点:python 位操作符 左移和右移 运算
[参考链接]
http://wangyan112.blog.51cto.com/3383033/1320143
http://www.cnblogs.com/yu-zhang/p/3708517.html

(个人理解,有误请指正,谢谢)
本题中不涉及位移运算,只涉及读取当前位的值
result << =1, (将result转换为2进制数,)向左移位(即下次操作从左向右添加数值)
result |= n & 1, 若n当前位为1,将result当前位赋值为1,否则赋值0(不赋值)
n>>=1, n向右移位(下次取值取从后往前数的下一位数字)

测试实例:

>>> bin(34)'0b100010'>>> n =34>>> n & 10>>> n>>=1>>> n & 11>>> n>>=1>>> n & 10>>> n>>=1>>> n & 10>>> n>>=1>>> n & 10>>> n>>=1>>> n & 11

191. Number of 1 Bits

Leetcode 题目链接
Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight).

For example, the 32-bit integer ’11’ has binary representation 00000000000000000000000000001011, so the function should return 3.

My solution: Beat 14.4% code which use python

class Solution:    # @param n, an integer    # @return an integer    def hammingWeight(self, n):        result = 0        for i in range(n.bit_length()):            result += n & 1            n >>= 1        return result

Beat 90%

class Solution:    # @param n, an integer    # @return an integer    def hammingWeight(self, n):        result = 0        while n:            n &= n - 1            result += 1        return result

n-1每次都n的最后一位1(不管其后有几位0)变为0,之后的所有0(也只有0,因为是最后一位1之后的数字)变为1.
n & (n-1) 将对上一步中,100…及减1所得的011….进行&操作,从而得到000…即:消去了最后一位1.
while n:循环,直到所有的1都被消掉,即进行的循环次数为1的个数。

(完全想不到)


231. Power of Two

Given an integer, write a function to determine if it is a power of two.

My Solution: Beat 58%

class Solution(object):    def isPowerOfTwo(self, n):        """        :type n: int        :rtype: bool        """        count = 0        result = True        if n < 0:            return False        for i in range(n.bit_length()):            count += n & 1            if (count>1):                 result = False                break            n >>= 1        if (count==0):            result = False        return result

刚开始没考虑到负数情况。负数不可能为2的power.
当为正数时,若为2的power, 则二进制除首位为1,其余全为0。

设count初始值为0,若有多位1,则不是2的power;若没有1位1(全为0),则也不是2的power。

Solution:

# Time:  O(1)# Space: O(1)## Given an integer, write a function to determine if it is a power of two.#class Solution:    # @param {integer} n    # @return {boolean}    def isPowerOfTwo(self, n):        return n > 0 and (n & (n - 1)) == 0class Solution2:    # @param {integer} n    # @return {boolean}    def isPowerOfTwo(self, n):        return n > 0 and (n & ~-n) == 0

~n: -n-1
~-n = n-1
These 2 methods are exactly the same.

与上题类似,
n>0: 2的power一定为正数
n & (n-1): 100…及减1所得的011….进行&操作,从而得到000…即:消去了最后一位1. 消去最后1位1后=0,说明首位为1,其余全为0. 所以是2的power。


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?

My Solution:

class Solution(object):    def isPowerOfFour(self, num):        """        :type num: int        :rtype: bool        """        if num <= 0 or (num & (num - 1)) != 0: return False        count = 0        for i in range(num.bit_length()/2+1):            count += num & 1            if count > 1: return False            num >>= 2        if count==0: return False        return True

与上题类似:
4的power:有且只有首位为1,且所在位数(长度)为奇数

Solution:

class Solution(object):    def isPowerOfFour(self, num):        """        :type num: int        :rtype: bool        """        return num > 0 and (num & (num - 1)) == 0 and \               ((num & 0b01010101010101010101010101010101) == num)# Time:  O(1)# Space: O(1)class Solution2(object):    def isPowerOfFour(self, num):        """        :type num: int        :rtype: bool        """        while num and not (num & 0b11):            num >>= 2        return (num == 1)

Solution 2:
while:
num: 当前num(减位后)不为0;
not ( num & 0b11 ): 当前num的后两位不为01,10,11.
即num必须为100…且0的个数为偶数。


371. Sum of Two Integers

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.

Example:
Given a = 1 and b = 2, return 3.

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

My Solution:(WRONG in same cases)

class Solution(object):    def getSum(self, a, b):        """        :type a: int        :type b: int        :rtype: int        """        result = 0        for i in range(max(a.bit_length(), b.bit_length())):            if (result & 1 == 0):                if (a&1==0 and b&1==0):                    result<<=1                elif ((a&1==0 and b&1==1) or (a&1==1 and b&1==0)):                    result |= 1                    result<<=1                elif (a&1==1 and b&1==1):                    result<<=1                    result |=  1            else:                if (a&1==0 and b&1==0):                    result<<=1                elif (a&1==0 and b&1==1) or (a&1==1 and b&1==0):                    result &=  0                    result<<=1                    result |= 1                elif (a&1==1 and b&1==1):                    result<<=1                    result |= 1            a>>=1            b>>=1        result1 = 0        for i in range(result.bit_length()):            result1 <<= 1            result1 |= result & 1            result >>= 1        return result1

Solution: (还没看懂)

# Time:  O(1)# Space: O(1)# Calculate the sum of two integers a and b,# but you are not allowed to use the operator + and -.## Example:# Given a = 1 and b = 2, return 3.class Solution(object):    def getSum(self, a, b):        """        :type a: int        :type b: int        :rtype: int        """        bit_length = 32        neg_bit, mask = (1 << bit_length) >> 1, ~(~0 << bit_length)        a = (a | ~mask) if (a & neg_bit) else (a & mask)        b = (b | ~mask) if (b & neg_bit) else (b & mask)        while b:            carry = a & b            a ^= b            a = (a | ~mask) if (a & neg_bit) else (a & mask)            b = carry << 1            b = (b | ~mask) if (b & neg_bit) else (b & mask)        return a

Another Solution in Cpp:

class Solution {public:    int getSum(int a, int b) {        if (b == 0) return a;        int sum = a ^ b;        int carry = (a & b) << 1;        return getSum(sum, carry);    }};class Solution {public:    int getSum(int a, int b) {        return b == 0 ? a : getSum(a ^ b, (a & b) << 1);    }};class Solution {public:    int getSum(int a, int b) {        while (b) {            int carry = (a & b) << 1;            a = a ^ b;            b = carry;        }        return a;    }};

389. Find the Difference

Given two strings s and t which consist of only lowercase letters.

String t is generated by random shuffling string s and then add one more letter at a random position.

Find the letter that was added in t.

Example:

Input:s = "abcd"t = "abcde"Output:eExplanation:'e' is the letter that was added.

Solution:

# Time:  O(n)# Space: O(1)# Given two strings s and t which consist of only lowercase letters.## String t is generated by random shuffling string s# and then add one more letter at a random position.## Find the letter that was added in t.## Example:## Input:# s = "abcd"# t = "abcde"## Output:# e## Explanation:# 'e' is the letter that was added.from operator import xorclass Solution(object):    def findTheDifference(self, s, t):        """        :type s: str        :type t: str        :rtype: str        """        return chr(reduce(xor, map(ord, s), 0) ^ reduce(xor, map(ord, t), 0))

ord(c):
Given a string of length one, return an integer representing the Unicode code point of the character when the argument is a unicode object, or the value of the byte when the argument is an 8-bit string. For example, ord(‘a’) returns the integer 97, ord(u’\u2020’) returns 8224. This is the inverse of chr() for 8-bit strings and of unichr() for unicode objects. If a unicode argument is given and Python was built with UCS2 Unicode, then the character’s code point must be in the range [0..65535] inclusive; otherwise the string length is two, and a TypeError will be raised.

map(function, iterable, …)

Apply function to every item of iterable and return a list of the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be extended withNoneitems. If function isNone, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is always a list.
1、对可迭代函数’iterable’中的每一个元素应用‘function’方法,将结果作为list返回。

>>> def add100(x):...     return x+100... >>> hh = [11,22,33]>>> map(add100,hh)[111, 122, 133]

2、如果给出了额外的可迭代参数,则对每个可迭代参数中的元素‘并行’的应用‘function’。(翻译的不好,这里的关键是‘并行’)

>>> def abc(a, b, c):...     return a*10000 + b*100 + c... >>> list1 = [11,22,33]>>> list2 = [44,55,66]>>> list3 = [77,88,99]>>> map(abc,list1,list2,list3)[114477, 225588, 336699]

在每个list中,取出了下标相同的元素,执行了abc()。

3、如果’function’给出的是‘None’,自动假定一个‘identity’函数

>>> list1 = [11,22,33]>>> map(None,list1)[11, 22, 33]>>> list1 = [11,22,33]>>> list2 = [44,55,66]>>> list3 = [77,88,99]>>> map(None,list1,list2,list3)[(11, 44, 77), (22, 55, 88), (33, 66, 99)]

401. Binary Watch

A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59).

Each LED represents a zero or one, with the least significant bit on the right.
Given a non-negative integer n which represents the number of LEDs that are currently on, return all possible times the watch could represent.

Example:

Input: n = 1
Return: [“1:00”, “2:00”, “4:00”, “8:00”, “0:01”, “0:02”, “0:04”, “0:08”, “0:16”, “0:32”]

# Time:  O(1)# Space: O(1)# A binary watch has 4 LEDs on the top which represent the hours (0-11),# and the 6 LEDs on the bottom represent the minutes (0-59).## Each LED represents a zero or one, with the least significant bit on the right.## For example, the above binary watch reads "3:25".## Given a non-negative integer n which represents the number of LEDs that are currently on,# return all possible times the watch could represent.## Example:## Input: n = 1# Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]# Note:# The order of output does not matter.# The hour must not contain a leading zero, for example "01:00" is not valid, it should be "1:00".class Solution(object):    def readBinaryWatch(self, num):        """        :type num: int        :rtype: List[str]        """        def bit_count(bits):            count = 0            while bits:                bits &= bits-1                count += 1            return count        return ['%d:%02d' % (h, m)            for h in xrange(12) for m in xrange(60)            if bit_count(h) + bit_count(m) == num]

使用191. Number of 1 bits 结论。在时间的定义范围内取值,当时钟与分钟的1 bits 数目相加为num, 即为所求。

(没有想到。。)

0 0