1787. 使所有区间的异或结果为零(动态规划)

Posted 尖子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1787. 使所有区间的异或结果为零(动态规划)相关的知识,希望对你有一定的参考价值。

给你一个整数数组 nums​​​ 和一个整数 k​​​​​ 。区间 [left, right](left <= right)的 异或结果 
是对下标位于 left 和 right(包括 left 和 right )之间所有元素进行 XOR 
运算的结果:nums[left] XOR nums[left+1] XOR ... XOR nums[right] 。
返回数组中 要更改的最小元素数 ,以使所有长度为 k 的区间异或结果等于零。 
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var minChanges = function(nums, k) {
    let max = 1 << (Math.max(...nums).toString(2).length);// 截枝xor为0,只需要考虑到当前数组最大值。
    let min = new Array(k).fill(Number.MAX_VALUE);
    let n = nums.length;
    let dp = new Array(k).fill(0).map(()=>new Array(max).fill(Number.MAX_VALUE));
    for(let i=0;i<k;i++){
        let cnt = 0;
        let map = new Map();
        for(let j=i;j<n;j+=k){
            map.set(nums[j], (map.get(nums[j])||0) + 1);
            cnt++;
        }
        if(i===0){ // 第 0 列:只需要考虑如何将该列变为 xor 即可
            for(let xor=0;xor<max;xor++){
                dp[0][xor] = Math.min( dp[0][xor], cnt - (map.get(xor)||0));
                min[0] = Math.min(min[0], dp[0][xor]);
            }
            
        }else{// 其他列:考虑与前面列的关系
            for(let xor=0;xor<max;xor++){
                dp[i][xor] = min[i - 1] + cnt; // 整列替换
                for (let [cur,val] of map.entries()) { // 部分替换
                    dp[i][xor] = Math.min(dp[i][xor], dp[i - 1][xor ^ cur] + cnt - val);
                }
                min[i] = Math.min(min[i], dp[i][xor]);
            }
        }
    }
    return dp[k-1][0];
};

let nums = [1,2,0,3,0], k = 1
console.log(nums, k, minChanges(nums,k))
nums = [3,4,5,2,1,7,3,4,7], k = 3
console.log(nums, k, minChanges(nums,k))
nums = [1,2,4,1,2,5,1,2,6], k = 3
console.log(nums, k, minChanges(nums,k))

示例 1:

输入:nums = [1,2,0,3,0], k = 1
输出:3
解释:将数组 [1,2,0,3,0] 修改为 [0,0,0,0,0]
示例 2:
输入:nums = [3,4,5,2,1,7,3,4,7], k = 3
输出:3
解释:将数组 [3,4,5,2,1,7,3,4,7] 修改为 [3,4,7,3,4,7,3,4,7]
示例 3:
输入:nums = [1,2,4,1,2,5,1,2,6], k = 3
输出:3
解释:将数组[1,2,4,1,2,5,1,2,6] 修改为 [1,2,3,1,2,3,1,2,3]
 

 

提示:
1 <= k <= nums.length <= 2000
​​​​​​0 <= nums[i] < 210

以上是关于1787. 使所有区间的异或结果为零(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章

1787. 使所有区间的异或结果为零

1787. 使所有区间的异或结果为零 / 剑指Offer56 - I. 数组中数字出现的次数 / 剑指Offer56 - II. 数组中数字出现的次数 II / 剑指Offer57.和为s的两个数字(

使所有区间的异或结果为零需要修改的元素的最少数(DP)

CodeForce-811C Vladik and Memorable Trip(动态规划)

LeetCode 1738. 找出第 K 大的异或坐标值(Java动态规划)

LeetCode 1738. 找出第 K 大的异或坐标值(Java动态规划)