【感觉很是绕脑弯的一道题,确实需要具备扎实的计算机组成知识】
题目
对数组 nums
执行 按位与 相当于对数组 nums
中的所有整数执行 按位与 。
- 例如,对
nums = [1, 5, 3]
来说,按位与等于1 & 5 & 3 = 1
。 - 同样,对
nums = [7]
而言,按位与等于7
。
给你一个正整数数组 candidates
。计算 candidates
中的数字每种组合下 按位与 的结果。 candidates
中的每个数字在每种组合中只能使用 一次 。
返回按位与结果大于 0
的 最长 组合的长度。
样例
示例 1:
输入:candidates = [16,17,71,62,12,24,14] 输出:4 解释:组合 [16,17,62,24] 的按位与结果是 16 & 17 & 62 & 24 = 16 > 0 。 组合长度是 4 。 可以证明不存在按位与结果大于 0 且长度大于 4 的组合。 注意,符合长度最大的组合可能不止一种。 例如,组合 [62,12,24,14] 的按位与结果是 62 & 12 & 24 & 14 = 8 > 0 。
示例 2:
输入:candidates = [8,8] 输出:2 解释:最长组合是 [8,8] ,按位与结果 8 & 8 = 8 > 0 。 组合长度是 2 ,所以返回 2 。
要求
1 <= candidates.length <= 105
1 <= candidates[i] <= 107
解题思路
首先得明确与运算的本质,本题是将数组中每一个数的二进制数的每一位相与(1&0=0,1&1=1,也就是只有全1相与才为1),如此得到的数结果要大于0(为0就是最后相与的到的全是0)而且要最大才满足条件,那分析到这里其实思路就已经出现了,那就是要最后的数里有尽可能多的1【指二进制数位】,那么本质还是一个找最大数呗,不过是找1的最大数位【最长组合的长度->哪些数包含了组成最大二进制数的’1‘】
代码
class Solution {
public:
int largestCombination(vector<int>& candidates) {
int ans=0;
for(int i=24;i>=0;i--)//24来自candidates【i】的最大值,题里给出10^7也就是24位2进制数
{int len=0;
for(int c:candidates)
{if(((c>>i)&1)==1)//带符号右移,寻找1的个数
len++;
ans=ans>len?ans:len;
}
}
return ans;
}
};
【感觉力扣题越来越像脑筋急转弯了,不过带来的新思路也是很奇特】