zoukankan      html  css  js  c++  java
  • [LeetCode 982] Triples with Bitwise AND Equal To Zero

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

    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. 1 <= A.length <= 1000
    2. 0 <= A[i] < 2^16

    Solution that you came up: there are 3 cases: 1. all 3 indices are the same; 2. 2 indices are the same; 3. all 3 indices are different.

    case 1: count how many 0s;

    case 2: has pattern(x, x, y), fix x then find y such that A[x] & A[y] is 0, there are 3 positions that we can put y into.

    case 3: dp[i] is the number of pairs(x != y) so far such that (A[x] & A[y]) == i. Loop through A and fix the 3rd position index of a triple, then check all possible pairs' & value to see if we can get a valid triple. If we can, add 3! (Order matters). After considering all possible triples that end at the current index, update dp[] using the current number as the 2nd index.

    Runtime is O(N * N + N * 2^16), space is O(2^16).

    class Solution {
        public int countTriplets(int[] A) {
            int ans = 0;
            //(0,0,0)
            for(int v : A) {
                if(v == 0) {
                    ans++;
                }
            }
            //(x,x,y),(x,y,x),(y,x,x)
            for(int i = 0; i < A.length; i++) {
                for(int j = 0; j < A.length; j++) {
                    if(j == i) {
                        continue;
                    }
                    if((A[i] & A[j]) == 0) {
                        ans += 3;
                    }
                }
            }
            //(x,y,z) and all its permutations
            //dp[i]: the number of pairs(x != y) so far such that (A[x] & A[y]) == i
            if(A.length >= 3) {
                int n = 1 << 16;
                int[] dp = new int[n];
                dp[A[0] & A[1]]++;
                for(int k = 2; k < A.length; k++) {
                    for(int v = 0; v < n; v++) {
                        if((v & A[k]) == 0) {
                            ans += dp[v] * 6;
                        }
                    }
                    for(int i = 0; i < k; i++) {
                        dp[A[i] & A[k]]++;
                    }
                }            
            }
            return ans;
        }
    }

    A more concise solution

    Instead of computing 3 separate cases, we can just define dp[i] as the number of index pairs (x, y) such that (A[x] & A[y]) == i. Then loop through all possible pairs including same index to update dp. Then we loop through A to fill in a 3rd index to make triples. Since each index is unique, we'll not have double counting. For each index, loop through all pairs' & value to check if we can make a valid triple, update final count. Both the runtime and space complexity are the same with the above solution.

    class Solution {
    public int countTriplets(int[] A) {
            int ans = 0;
            int[] dp = new int[1 << 16];
            for(int i = 0; i < A.length; i++){
                for(int j = 0; j < A.length; j++){
                    int v = A[i] & A[j];
                    dp[v]++;
                }
            }
            for(int i = 0; i < A.length; i++){
                for(int j = 0; j < dp.length; j++) {
                    if((A[i] & j) == 0){
                        //use i as the 3rd index
                        ans += dp[j];
                    }
                }
            }
            return ans;
        }
    }
  • 相关阅读:
    ES vm报错
    ln -s /usr/local/jdk1.8.0_201/bin/java /bin/java
    docker压缩导入导出
    微软各种资源整理(迅雷下载),感谢站长。
    python打开文件的访问方式
    docker换源
    selinux
    ElasticsearchException: java.io.IOException: failed to read [id:0, file:/data/elasticsearch/nodes/0/_state/global-0.st]
    带了纸和笔,要记哪些东西?
    redis命令行批量删除匹配到的key
  • 原文地址:https://www.cnblogs.com/lz87/p/13733327.html
Copyright © 2011-2022 走看看