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

题目描述

给你一个整数数组 nums​​​ 和一个整数 k​​​​​ 。区间 [left, right](left <= right)的 异或结果 是对下标位于 left 和 right(包括 left 和 right )之间所有元素进行 XOR 运算的结果:nums[left] XOR nums[left+1] XOR ... XOR nums[right] 。

返回数组中 要更改的最小元素数 ,以使所有长度为 k 的区间异或结果等于零。

思路分析

  • 分组背包:按照区间长度为k的求模来分为k个组
  • 状态转移函数f(i,mask)=min{f(i−1,mask⊕x)+size(i)−count(i,x)}
    • 优化为两个部分
      • f(i−1,mask⊕x)-count(i,x)分为f(i−1,mask⊕x)f(i−1,mask⊕x)-count(i,x)

      • 这里的f(i−1,mask⊕x)可以直接通过*min_element(f.begin(), f.end())获取最小元素(后面>i的已经通过vector<int> f(MAXX, n)取最大值了)

官方题解如下

  • 基于官方题解,修改了部分
  • class Solution {
    private:
        // x 的范围为 [0, 2^10)
        static constexpr int MAXX = 1 << 10;
        
    public:
        int minChanges(vector<int>& nums, int k) {
            int n = nums.size();
            vector<int> f(MAXX, n);
            // 边界条件 f(-1,0)=0
            f[0] = 0;
            
            for (int i = 0; i < k; ++i) {
                // 第 i 个组的哈希映射
                unordered_map<int, int> cnt;
                int size = 0;
                for (int j = i; j < n; j += k) {
                    ++cnt[nums[j]];
                    ++size;
                }
    
                // 求出 t2
                int t2min = *min_element(f.begin(), f.end());
    
                vector<int> g(MAXX, t2min);
                for (int mask = 0; mask < MAXX; ++mask) 
                    for (auto [x, countx]: cnt) 
                        g[mask] = min(g[mask], f[mask ^ x] - countx);
                
                // 别忘了加上 size
                for(auto &t:g)
                    t+=size;
                f = g;
            }
    
            return f[0];
        }
    };

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值