力扣刷题——2680. 最大或值
可以依次遍历这个数组去找答案,但是普通遍历的话不是最优的方法。更好的方法是保存前缀或和后缀或数值,这样能够更快的获取其他数字的或值,可以在O(n)下完成解答
class Solution {
public:
long long maximumOr(vector<int>& nums, int k)
{
long long res = 0;
int n = nums.size();
vector<long long> prefix(n, 0);
vector<long long> suffix(n, 0);
for (int i = 1; i < n; i++)
{
prefix[i] = prefix[i - 1] | nums[i - 1];
suffix[n - 1 - i] = suffix[n- i] | nums[n- i];
}
for (int i = 0; i < n; i++)
{
long long tem = prefix[i] | suffix[i] | ((long long)nums[i] << k);
res = max(res, tem);
}
return res;
}
};
还有种做法可以省去前缀或和后缀或的数组空间,主要是通过两个数字,一个维护出现多次的位数multiBits,另一个维护出现过一次及以上的位数oneBits。因为出现过多次的位数在最后的结果中,是必定出现的,因此在枚举答案的时候,只需要和当前枚举的数字作或就行。还要注意另一种情况是,非当前数字的位也可能只出现一次,这种状况需要当前数字与oneBits作异或,排除当前数字移位对答案的影响。
class Solution
{
public:
long long maximumOr(vector<int> &nums, int k)
{
long long res = 0;
long long oneBits = 0, multiBits = 0;
for (int i = 0; i < nums.size(); i++)
{
multiBits = multiBits | (oneBits & nums[i]);
oneBits = oneBits | nums[i];
}
for (int i = 0; i < nums.size(); i++)
{
res = max(res, multiBits | (nums[i] << k) | (nums[i] ^ oneBits));
}
return res;
}
};

浙公网安备 33010602011771号