力扣刷题——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;
    }
};
posted @ 2025-03-25 14:49  SuzumiyaYui  阅读(6)  评论(0)    收藏  举报