1787. 使所有区间的异或结果为零(动态规划)
Posted 尖子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1787. 使所有区间的异或结果为零(动态规划)相关的知识,希望对你有一定的参考价值。
题目来源: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. 使所有区间的异或结果为零 / 剑指Offer56 - I. 数组中数字出现的次数 / 剑指Offer56 - II. 数组中数字出现的次数 II / 剑指Offer57.和为s的两个数字(
CodeForce-811C Vladik and Memorable Trip(动态规划)