【982】按位与为零的三元组

给你一个整数数组 nums ,返回其中 按位与三元组 的数目。

按位与三元组 是由下标 (i, j, k) 组成的三元组,并满足下述全部条件:

0 <= i < nums.length

0 <= j < nums.length

0 <= k < nums.length

nums[i] & nums[j] & nums[k] == 0 ,其中 & 表示按位与运算符。

示例 1:

输入:nums = [2,1,3]

输出:12

解释:可以选出如下 i, j, k 三元组:

(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

示例 2:

输入:nums = [0,0,0]

输出:27

提示:

1 <= nums.length <= 1000

0 <= nums[i] < 216

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/triples-with-bitwise-and-equal-to-zero

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

鼠鼠我啊,学艺不精,第一个入脑的就是暴力解,最后还是通过了。

这里的暴力不是完全的暴力,因为还是做了预处理,就是方法比较好懂而已。

首先观察,思考一下每种可能:

  1. 如果这个数组大小比2小怎么办。

  1. 如果遇到一个0怎么办。

  1. 如果遇到两个数按位与刚好能成的怎么办。

  1. 如果遇到三个数按位与能成怎么办。

先不看第一条。首先,遇到一个0,说明其它数是多少不重要。假设这个0是第i个数(从0开始计数),那么它能成的可能就有3*(l-i)*(l-i-1)+1种,+1的原因是三个自己也是能成的。其次,如果两个数刚好能成,则第三个数不重要。当第三个数不存在于这两个数之间时,一共有6*(l-i-1)种。当第三个数存在于这两个数之间时,一共有6种。所以第三条一共有6*(l-i)种。第四条很简单,三个数排列组合,基本问题,答案是6种。

按道理,这样加起来确实做过了预处理。

但我第一次没过。为什么呢?

有没有可能,如果全是第三种情况,按位与也是要时间的。记不记得算法课讲过,记录子问题的结果以减少计算时间?所以,我们仔细观察会发现,如果是第三种情况,其实它有两个数的按位与结果是已经算过的。所以我们要做的就是取一个数把它存下来。

这样就通过了。

class Solution {
public:
    int countTriplets(vector& nums) {
        int l=nums.size();
        //0,3*pow(l,2),
        //如果两个数按位与是0,3*2*(l-1);
        //如果三个数按位与是0,6
        int cont=0;
        int i;
        for(i=0;i

但感觉效率很低。

为什么呢。我也不知道为什么,感觉明明少算了很多,但从结果来看没有少算。是因为三层循环吗。需要大佬指点迷津。

学了另一种写法。遍历所有的两数组合,记录结果。然后遍历两数集合的所有结果,找出三个数也是0的组合。

class Solution {
public:
    int countTriplets(vector &nums) {
        int cnt[1 << 16]{};
        for (int x : nums)
            for (int y : nums)
                ++cnt[x & y];
        int ans = 0;
        for (int x : nums)
            for (int y = 0; y < 1 << 16; ++y)
                if ((x & y) == 0)
                    ans += cnt[y];
        return ans;
    }
};

你可能感兴趣的:(刷题合集,leetcode,c++,算法)