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
标签:示例,nums,number,1787,异或,数组,动态 来源: https://blog.51cto.com/u_15201483/2823653