leetcode刷题笔记-bit

2871. Split Array Into Maximum Number of Subarrays

class Solution:
    def maxSubarrays(self, nums: List[int]) -> int:
        '''
        Because (x & y) <= x and (x & y) <= y,
        so the score(array) <= score(subarray).

        If the score of A is x,
        then the score of each subarray of A bigger or equal to x.

        If x > 0,
        2x > x,
        so we won't split A,
        return 1.

        If x == 0,
        so we may split A,
        into multiple subarray with score 0.

        So the real problem is,
        split A into as many subarray as possbile,
        with socre 0

        [0,8,0,0,0,23] 23 will & with pre 0
        '''
        re = 0
        total = -1  # all bits are 1
        for n in nums:
            total &= n
            if total == 0:
                re += 1
                total = -1

        return max(1, re)

2311. Longest Binary Subsequence Less Than or Equal to K

class Solution:
    def longestSubsequence(self, s: str, k: int) -> int:
        '''
        dp[i] means the minimum value of the subsequence with length i
        Time O(n^2)
        Space O(n)
        
        dp = [0]
        for v in map(int, s):  # 从头往后拿s的字母,并转为Int
            if dp[-1] * 2 + v <= k:  # 拿后面的数字,前面的进一位
                dp.append(dp[-1] * 2 + v)
            for i in range(len(dp) - 1, 0, -1):
                dp[i] = min(dp[i], dp[i - 1] * 2 + v)  #  不要i的那位,换成当前这个位置的数,即v
        return len(dp) - 1
        ''' 

        '''
        Greedy
        拿所有的0, 然后尽量的从右边拿1
        Time O(n)
        Space O(1)
        '''

        re = 0
        n = len(s)
        bit = 1  # 这一位如果是1代表的值

        for v in map(int, s[::-1]):  # 为了尽量从右边拿1, 这些1和0构成的数要小于k
            if (v == 0 or bit <= k):
                k -= bit * (v - 0)
                re += 1
            bit = bit << 1
        return re

1986. Minimum Number of Work Sessions to Finish the Tasks

class Solution:
    def minSessions(self, tasks: List[int], sessionTime: int) -> int:

        '''
Let dp(mask, remainTime) is the minimum of work sessions needed to finish all the tasks represent by mask (where ith bit = 0 means tasks[i] need to proceed) with the remainTime we have for the current session.
        '''

        '''
        # O(2^n * sessionTime * n)  mask 有2^n种情况, 每个worksession都要考虑2^n,因为DP是二维,每个dp里面要for loop N
        n = len(tasks)  # the number of tasks
        @lru_cache(None)
        def dp(mask, remainTime):
            if mask == (1 << n) - 1:  # all the tasks are marked as 1 (finished)
                return 0
            
            ans = sys.maxsize

            for i in range(n):  # check each task is done or not
                if mask & (1 << i) == 0:  # this task is not done
                    if tasks[i] <= remainTime:
                        ans = min(ans, dp(mask | (1<<i), remainTime-tasks[i]))
                    else:
                        ans = min(ans, 1 + dp(mask | (1<<i), sessionTime - tasks[i]))
            return ans
        return dp(0, 0)  # 第一维度,都是0表示tasks都没被处理, 第二纬0表示当前开的worksession 剩下时间是0,意味着要重新开一个worksession  

        '''

        # 改进 O(2^n * n) dp(mask) return (the minimum of work sessions needed, remainTime) 
        n = len(tasks)
        @lru_cache(None)
        def dp(mask):
            if mask == (1 << n) - 1:  # all the tasks are marked as 1 (finished)
                return 0, 0
            ans = sys.maxsize
            ansRemainTime = 0

            for i in range(n):
                if mask & (1 << i) == 0:
                    newMask = mask | (1<<i)
                    cnt, remainTime = dp(newMask)

                    if tasks[i] <= remainTime:
                        remainTime = remainTime - tasks[i]
                    else:  # neet to create a new session
                        cnt += 1 
                        remainTime = sessionTime - tasks[i]
                    if cnt < ans or cnt == ans and remainTime > ansRemainTime:
                        ans = cnt
                        ansRemainTime = remainTime
            return ans, ansRemainTime
        
        return dp(0)[0]

338. Counting Bits

class Solution(object):
    def countBits(self, num):
        dp = [0] * (num+1)
        for i in xrange(num+1):
            dp[i] = dp[i/2] + i%2
        return dp

260. Single Number III

class Solution(object):
    def singleNumber(self, nums):
        xor = n1 = n2 = 0
        # find n1 xor n2
        for n in nums:
            xor ^= n  
# if a bit in xor is 1, means n1, n2 in this bit is different
# Thus, all the numbers can be partitioned into two groups according to their bits at location i.
# the first group consists of all numbers whose bits at i is 0.
# the second group consists of all numbers whose bits at i is 1.
        bit = 1
        while bit & xor == 0:
            bit = bit << 1 # 位移1bit
        
        for n in nums:
            if n & bit:
                n1 ^= n
            else:
                n2 ^= n
        return [n1, n2]

137. Single Number II

class Solution(object):
    def singleNumber(self, nums):
        ones = twos = 0
        for n in nums:
            ones = ones^n & ~twos
            twos = twos^n & ~ones
        return ones|twos

477. Total Hamming Distance

class Solution(object):
    def totalHammingDistance(self, nums):
        bits = [[0,0] for _ in xrange(32)]
        for n in nums:
            for i in xrange(32):
                bits[i][n%2] += 1
                n /= 2
        return sum(x*y for x,y in bits)

136. Single Number

这题关键是最多的也只重复2次。

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        res = nums[0]
        for i in xrange(1, len(nums)):
            res ^= nums[i]

        return res

 return sum(set(nums))*2 - sum(nums)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值