Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 2680. Maximum OR

Woodyiiiiiii opened this issue · comments

Leetcode 2680. Maximum OR

2680. Maximum OR

这道题是双周赛104第三题,我做的不理想。

首先思考,为了让最后的或值最大,首先要考虑长度,也就是1更前面。所以不妨只选定一个值,然后左移k个位置,当然这个值肯定是在于当前数组中1更前的数值。

那么接下来问题是如何选中这个值呢?不妨直接暴力,尝试每个左移后的值最后的或值结果,然后对比。但同时这个操作也是在O(1)复杂度下的,所以可以先计算或值,或者用前后缀数组。

func maximumOr(nums []int, k int) int64 {
    first := 0
	for i := 0; i < len(nums); i++ {
		first |= nums[i]
	}
	cnt := make([]int, 32)
	for i := 0; i < len(nums); i++ {
		for j := 0; j < 32; j++ {
			if nums[i]&(1<<j) != 0 {
				cnt[j]++
			}
		}
	}
	var mx int64
	for i := 0; i < len(nums); i++ {
		t := int64(first)
		for j := 0; j < 32; j++ {
			if nums[i]&(1<<j) != 0 && cnt[j] == 1 {
				t ^= 1 << j
			}
		}
		num := int64(nums[i])
		for j := 0; j < k; j++ {
			num <<= 1
		}
		mx = max1(mx, (num | t))
	}
	return mx
}

func max1(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}
class Solution {
    public long maximumOr(int[] nums, int k) {
        int n = nums.length;
        int[] suf = new int[n];
        for (int i = n - 1; i >= 0; i--) {
            suf[i] = i + 1 == n ? nums[i] : (nums[i] | suf[i + 1]);
        }
        long pre = 0, ans = 0;
        for (int i = 0; i < n; i++) {
            long num = nums[i];
            int t = k;
            while (t-- > 0) {
                num <<= 1;
            }
            if (i - 1 >= 0) {
                num |= pre;
            }
            if (i + 1 < n) {
                num |= suf[i + 1];
            }
            ans = Math.max(ans, num);
            pre |= nums[i];
        }
        return ans;
    }
}