1. 程式人生 > >LeetCode系列Easy【1】 Algorithms

LeetCode系列Easy【1】 Algorithms

  • 2016.10.09啟程。。

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 result if __name__ == '__main__': print Solution().reverseBits(1
)

(個人理解,有誤請指正,謝謝)
本題中不涉及位移運算,只涉及讀取當前位的值
result << =1, (將result轉換為2進位制數,)向左移位(即下次操作從左向右新增數值)
result |= n & 1, 若n當前位為1,將result當前位賦值為1,否則賦值0(不賦值)
n>>=1, n向右移位(下次取值取從後往前數的下一位數字)

測試例項:

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

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)) == 0

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

Explanation:
'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 xor

class 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, 即為所求。

(沒有想到。。)