LeetCode双周赛T3

求出数组中最大序列值

题目描述

给定一个整数数组 nums 和一个正整数 k。定义长度为 2 * k 的序列 seq 的值为:

(seq[0] OR seq[1] OR ... OR seq[k - 1]) XOR (seq[k] OR seq[k + 1] OR ... OR seq[2 * k - 1])

其中 OR 表示按位或操作,XOR 表示按位异或操作。请你求出 nums 中所有长度为 2 * k 的子序列的最大值。

代码实现

const int N = 410;
bool suf[N][N/2][130], pre[N][N/2][130];

class Solution {
public:
    int maxValue(vector<int>& nums, int k) {
        int MX = 1 << 7; // 状态的最大值
        int n = nums.size(); // 数组长度
        int ans = 0; // 最终结果
        memset(suf, false, sizeof suf); // 初始化 suf 数组
        memset(pre, false, sizeof pre); // 初始化 pre 数组
        suf[n][0][0] = true; // 初始化 suf 数组的起始状态
        pre[0][0][0] = true; // 初始化 pre 数组的起始状态
        
        // 计算 suf 数组
        for (int i = n - 1; i >= k; i--) {
            int v = nums[i];
            bool temp_suf[N/2][130];
            memcpy(temp_suf, suf[i + 1], sizeof temp_suf); // 保存 suf[i + 1] 的内容
            memcpy(suf[i], temp_suf, sizeof suf[i]); // 将 temp_suf 赋值给 suf[i]
            for (int j = 1; j <= k; j++) {
                for (int x = 0; x < MX; x++) {
                    if (suf[i + 1][j - 1][x]) {
                        suf[i][j][x | v] = true; // 更新 suf[i][j][x] 的状态
                    }
                }
            }
        }
        
        // 计算 pre 数组
        for (int i = 0; i < n - k; i++) {
            int v = nums[i];
            // 使用临时数组保存 pre[i] 的内容
            bool temp_pre[N/2][130];
            memcpy(temp_pre, pre[i], sizeof temp_pre);
            
            // 将 pre[i] 赋值为 temp_pre
            memcpy(pre[i + 1], temp_pre, sizeof pre[i + 1]);
            for (int j = 1; j <= k; j++) {
                for (int x = 0; x < MX; x++) {
                    if (pre[i][j - 1][x]) {
                        pre[i + 1][j][x | v] = true; // 更新 pre[i + 1][j][x] 的状态
                    }
                }
            }
        }
        
        // 计算最终结果
        for (int i = k; i < n - k; i++) {
            for (int x = 0; x < MX; x++) {
                if (pre[i + 1][k][x]) {
                    for (int y = 0; y < MX; y++) {
                        if (suf[i + 1][k][y]) {
                            ans = max(ans, x ^ y); // 更新最大值
                        }
                    }
                }
            }
        }
        
        return ans; // 返回最终结果
    }
};

代码解释

  1. 初始化:

    • sufpre 数组用来记录状态,其中 suf[i][j][x] 表示从 in-1 这些数中能否选择 j 个数,使它们的按位或的结果为 x
    • pre[i][j][x] 表示在数组的前 i 个元素中,是否能选择 j 个数使它们的按位或结果为 x
  2. 计算 suf 数组:

    • 从后向前遍历 nums 数组,更新 suf 数组的状态。
  3. 计算 pre 数组:

    • 从前向后遍历 nums 数组,更新 pre 数组的状态。使用临时数组 temp_pre 进行状态保存和复制,避免覆盖问题。
  4. 计算最大值:

    • 遍历所有可能的状态组合,找到最大值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值