LeetCode Python 位操作 1

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode Python 位操作 1相关的知识,希望对你有一定的参考价值。

Python 位操作:

按位与 &, 按位或 |

体会不到

按位异或 ^

num ^ num = 0

左移 <<

num << 1 == num * 2**1

右移 >>

num >> 2 == num / 2**2

取反 ~

~num == -(num + 1)

 

1. Single Number

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

关键点在于相同整数按位异或为0, 整数与0异或不变, 一个 reduce 搞定. LeetCode 执行效率击败 18.9%.

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        return reduce(lambda x,y: x^y, nums)

 

2. Single Number II

Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

下三路的解法, 如果看到这个答案, 就应该问一下 sum 和 set 的时间空间复杂度各是多少, 为什么. LeetCode: 72.45%.

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        return (sum(set(nums)) * 3 - sum(nums)) / 2

 

3. 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?

首先, Python 没有原生对于 unsigned integer 的支持, 其次, 这个是同样下三路的解法. LeetCode: 85.2%.

class Solution:
    # @param n, an integer
    # @return an integer
    def reverseBits(self, n):
        string = bin(n)
        if n >= 0:
            string = string[:2] + string[2:].zfill(32)[::-1]
        else:
            string = string[:3] + string[3:].zfill(32)[::-1]
            
        return int(string, 2)

 

4. Number of 1 Bits

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.

这样刷题一点意思都没有, count 的时间空间复杂度是多少. LeetCode: 62.81%.

class Solution(object):
    def hammingWeight(self, n):
        """
        :type n: int
        :rtype: int
        """
        string = bin(n)
        return string.count("1")

 

5. Bitwise AND of Numbers Range

Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.

For example, given the range [5, 7], you should return 4.

如果用 range, 会报内存不足, 用 xrange 会报超时. 我自己把 [0, 2147483647] 带入, 确实跑不动.

class Solution(object):
    def rangeBitwiseAnd(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        return reduce(lambda x,y: x&y, xrange(m, n+1))

观察一下, 其实它的关键是, log(n, 2) 比 log(m, 2) 大多少, 如果大于 1, 那么肯定就是0, 如果小于 1, 就再进行 reduce. LeetCode: 2.52%. 

class Solution(object):
    def rangeBitwiseAnd(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        if m == 0:
            return 0
        
        from math import log
        logm = log(m, 2)
        logn = log(n, 2)
        
        if logn - logm >= 1:
            return 0
            
        return reduce(lambda x,y: x&y, xrange(m, n+1))

而使用 log 是明显的作弊, 再顺着刚才的思路, 之前都是从 m 开始考虑, 现在从 n 开始考虑, 因为 & 操作会使 n 迅速下降, 两种情况, 一种是遍历 [m, n] 的 &, 另一种半路上就有0出来了. 并且, 我相信耗时的大户应该是 xrange, 位操作本身应该很快. LeetCode: 70.18%.

class Solution(object):
    def rangeBitwiseAnd(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        while m < n:
            n &= n - 1
            
        return n

增加 if n == 0 判断, 如果是 0 就 break, 看看能提升多少. LeetCode: 73.09%.

class Solution(object):
    def rangeBitwiseAnd(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        while m < n:
            n &= n - 1
            if n == 0:
                break
            
        return n

 

6. Power of Two

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

首先, 2的0次方为 1, 因此 n >= 1, 然后, 就是对 n 执行 >>= i, 如果 n 是 2 的幂, 那么 n >> i << i == n, 注意我们的目标是计算 i 让 n >> i == 2, 所以 i - 1. LeetCode: 45.27%.

class Solution(object):
    def isPowerOfTwo(self, n):
        """
        :type n: int
        :rtype: bool
        """
        if n < 1:
            return False
        
        i, m = 0, n
        while m:
            m >>= 1
            i += 1
    
        return n >> (i - 1) << (i - 1) == n

 

260. Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

首先是下三路的解法, 必然会超时

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        results = []
        for i in set(nums):
            if nums.count(i) == 1:
                results.append(i)
            
            if len(results) == 2:
                return results

应该还是在考察位操作, 相同的数变成 0 而不同相同的数留下来. 如果全局异或, 最终的值是两个数字的异或. 这个涉及到位操作的细节, 凑不出来了.

我不准备用位操作解这个问题, collections 这个神库里面有个 Counter 类, 参数是 iterable 的对象, 对对象中的 hashable 对象进行计数. 

sorted 可以对字典的 values 进行排序. LeetCode: 45.7%.

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        from collections import Counter
        counter = Counter(nums)
        return [_[0] for _ in sorted(counter.items(), key=lambda x: x[1])[:2]]
        

 

268. Missing Number

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.

For example,
Given nums = [0, 1, 3] return 2.

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

等差数列之和, LeetCode: 78.18%.

class Solution(object):
    def missingNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)
        gauss_sum = length * (length - 1) / 2 + length
        nums_sum = sum(nums)
        return gauss_sum - nums_sum

 

318. Maximum Product of Word Lengths

Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.

Example 1:

Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"]
Return 16
The two words can be "abcw", "xtfn".

Example 2:

Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"]
Return 4
The two words can be "ab", "cd".

Example 3:

Given ["a", "aa", "aaa", "aaaa"]
Return 0
No such pair of words.

相当然的解法是遍历列表配合 set, 结果必然超时了.

class Solution(object):
    def maxProduct(self, words):
        """
        :type words: List[str]
        :rtype: int
        """
        results = [0]
        length = len(words)
        for i in xrange(length):
            item_i = words[i]
            for item_j in words[i:]:
                if len(set(item_i + item_j)) == len(set(item_i)) + len(set(item_j)):
                    results.append(len(item_i) * len(item_j))
        
        return max(results)

两个 for, 复杂度是 O(n**2), 不用跑都知道会超时. 如果能降到 O(nlogn) 说不定还有戏. 那能知道什么时候该停下么? 不知道, 先过.

 

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?

tmp > 1 也就是最小值 >>= 到 4的0次幂, 也就是 1, 然后再还原回来. LeetCode: 70.80%

class Solution(object):
    def isPowerOfFour(self, num):
        """
        :type num: int
        :rtype: bool
        """
        if num < 1:
            return False
        
        i, tmp = 0, num
        while tmp > 1:
            tmp >>= 2
            i += 2
        
        return num >> i << i == num

 

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.

完全没想法, 过.

 

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:
e

Explanation:
‘e‘ is the letter that was added.

没想法.

 














以上是关于LeetCode Python 位操作 1的主要内容,如果未能解决你的问题,请参考以下文章

位操作系列2-leetcode136(c++/python)

LeetCode 1486 数组异或操作[位运算 数学] HERODING的LeetCode之路

leetcode?pythonSum Of Two Number

p83 颠倒二进制位(leetcode 190)

python算法

Leetcode刷题Python LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色