zoukankan      html  css  js  c++  java
  • Leetcode: 982. Triples with Bitwise AND Equal To Zero

    Description

    Given an array of integers A, find the number of triples of indices (i, j, k) such that:
    
    0 <= i < A.length
    0 <= j < A.length
    0 <= k < A.length
    A[i] & A[j] & A[k] == 0, where & represents the bitwise-AND operator.
    

    Example

     Input: [2,1,3]
    Output: 12
    Explanation: We could choose the following i, j, k triples:
    (i=0, j=0, k=1) : 2 & 2 & 1
    (i=0, j=1, k=0) : 2 & 1 & 2
    (i=0, j=1, k=1) : 2 & 1 & 1
    (i=0, j=1, k=2) : 2 & 1 & 3
    (i=0, j=2, k=1) : 2 & 3 & 1
    (i=1, j=0, k=0) : 1 & 2 & 2
    (i=1, j=0, k=1) : 1 & 2 & 1
    (i=1, j=0, k=2) : 1 & 2 & 3
    (i=1, j=1, k=0) : 1 & 1 & 2
    (i=1, j=2, k=0) : 1 & 3 & 2
    (i=2, j=0, k=1) : 3 & 2 & 1
    (i=2, j=1, k=0) : 3 & 1 & 2
    

    Note

    1 <= A.length <= 1000
    0 <= A[i] < 2^16
    

    分析

    之前想过用 bit 位分类,但是总有遗漏的情况无法计算~
    
    class Solution(object):
        def _do(self, N):         
            m = len('{0:b}'.format(max(N)))
            ssum, total = 0, len(N)**3
            dp = []
            
            def rr(n, h, i):
                if i > 16 or len(n) == 0 or len(h) == 0:
                    return 0
                v = 1 << (i-1)
                l1 = sum([1 for j in n if j & v != 0])
                l2 = sum([1 for j in h if j & v != 0])
                if l1*l2 == 0:
                    return rr(n, h, i+1)
                return (l1+l2)**3 -l1**3 -l2**3 + rr(n, [j for j in h if j & v == 0] , i+1) + rr([j for j in n if j &v ==0], h , i+1)
                    
            for i in range(1, m+1):
                v  = 1 << (i-1)
                has, noth = [], []
                for j in N:
                    if j & v != 0: 
                        has.append(j)
                    else:
                        noth.append(j)
                t = rr(has, [j for j in dp], i)
                ssum += len(has)**3 + t
                print(dp, has, t)
                N = noth
                dp += has
    为了节省时间,结果写的贼复杂。还出错了~
    

    code

    class Solution(object):
        def countTriplets(self, N):
            """
            :type A: List[int]
            :rtype: int
            """
            L = len(N)
            m = max(N)
            dp = [0 for _ in range(m+1)]
            for i in range(L):
                for j in range(L):
                    dp[N[i]&N[j]] += 1
            ssum = 0
            for j in range(len(dp)):
                if dp[j] == 0:
                    continue
                for i in range(L):
                    if N[i] & j == 0:
                        ssum += dp[j]
            return ssum
    
    

    总结

    Runtime: 3976 ms, faster than 61.54% of Python online submissions for Triples with Bitwise AND Equal To Zero.
    Memory Usage: 15.5 MB, less than 100.00% of Python online submissions for Triples with Bitwise AND Equal To Zero.
    
    • 之前一直在寻找有效的优化方法,但是自己思考的方法总有遗漏~
    • 本题可以推广到 n 个数的 &, + 等等问题,只要先计算 2 个数的问题,依次循环。这样就等于是 log2 的降维,和快速幂有点类似
  • 相关阅读:
    js刷新
    getHibernateTemplate()为NUll
    struts2+hibernate+spring+jquery返回json List列表
    windowopen
    web配置详解
    缓存
    uuid-不好之处
    多对多转化一对多
    多对多拆成两个 多对一
    我的github地址账号和密码
  • 原文地址:https://www.cnblogs.com/tmortred/p/13275455.html
Copyright © 2011-2022 走看看