LeetCode-in-Java

3630. Partition Array for Maximum XOR and AND

Hard

You are given an integer array nums.

Partition the array into three (possibly empty) subsequences A, B, and C such that every element of nums belongs to exactly one subsequence.

Your goal is to maximize the value of: XOR(A) + AND(B) + XOR(C)

where:

Return the maximum value achievable.

Note: If multiple partitions result in the same maximum sum, you can consider any one of them.

Example 1:

Input: nums = [2,3]

Output: 5

Explanation:

One optimal partition is:

The maximum value of: XOR(A) + AND(B) + XOR(C) = 3 + 2 + 0 = 5. Thus, the answer is 5.

Example 2:

Input: nums = [1,3,2]

Output: 6

Explanation:

One optimal partition is:

The maximum value of: XOR(A) + AND(B) + XOR(C) = 1 + 2 + 3 = 6. Thus, the answer is 6.

Example 3:

Input: nums = [2,3,6,7]

Output: 15

Explanation:

One optimal partition is:

The maximum value of: XOR(A) + AND(B) + XOR(C) = 7 + 2 + 6 = 15. Thus, the answer is 15.

Constraints:

Solution

public class Solution {
    public long maximizeXorAndXor(int[] nums) {
        int n = nums.length;
        int full = 1 << n;
        int[] xorMask = new int[full];
        int[] andMask = new int[full];
        int[] orMask = new int[full];
        for (int mask = 1; mask < full; mask++) {
            int lb = mask & -mask;
            int i = Integer.numberOfTrailingZeros(lb);
            int prev = mask ^ lb;
            xorMask[mask] = xorMask[prev] ^ nums[i];
            andMask[mask] = prev == 0 ? nums[i] : andMask[prev] & nums[i];
            orMask[mask] = orMask[prev] | nums[i];
        }
        long best = 0;
        int all = full - 1;
        for (int b = 0; b < full; b++) {
            long andB = andMask[b];
            int rest = all ^ b;
            if (andB + 2L * orMask[rest] <= best) {
                continue;
            }
            for (int a = rest; ; a = (a - 1) & rest) {
                int c = rest ^ a;
                long sum = xorMask[a] + andB + xorMask[c];
                if (sum > best) {
                    best = sum;
                }
                if (a == 0) {
                    break;
                }
            }
        }
        return best;
    }
}