当前位置: 首页 > article >正文

Leetcode3287:求出数组中最大序列值

题目描述:

给你一个整数数组 nums 和一个  整数 k 。

定义长度为 2 * x 的序列 seq 的  为:

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

请你求出 nums 中所有长度为 2 * k 的子序列的 最大值 。

代码思路:

  1. 计算数组中所有数的按位或结果

    mx = reduce(lambda x,y : x | y, nums)

    这一步是为了确定所有可能的按位或结果的上限,因为任何数的按位或结果不会超过这个上限。

  2. 初始化动态规划数组

    • f 数组用于存储从数组右半部分选择 j 个数,能否通过按位或得到某个值 x
    • f[i][j][x] 表示在 nums[i] 到 nums[n-1] 中选择 j 个数,能否通过按位或得到 x
    • pre 数组用于存储从数组左半部分选择 j 个数,能否通过按位或得到某个值 x
    • pre[i][j][x] 表示在 nums[0] 到 nums[i] 中选择 j 个数,能否通过按位或得到 x
  3. 填充 f 数组(从右向左遍历数组):

    • 通过动态规划,从右向左遍历数组,更新 f 数组。
    • 对于每个位置 i 和每个可能的选取数量 j,以及每个可能的按位或结果 x,检查是否可以通过加入当前数 nums[i] 来更新结果。
  4. 填充 pre 数组(从左向右遍历数组):

    • 使用类似的方法从左向右遍历数组,更新 pre 数组。
  5. 计算最终结果

    • 遍历所有可能的分割点 i,将数组分为左半部分和右半部分。
    • 对于每个分割点,检查左半部分和右半部分能否分别通过选取 k 个数得到某个值 x 和 y
    • 计算 x ^ y 并更新最大值 ans
  6. 返回结果

    • 返回计算得到的最大值 ans

代码实现:

class Solution:
    def maxValue(self, nums: List[int], k: int) -> int:
        mx = reduce(lambda x,y : x | y,nums)
        n = len(nums)

        # f[i][j][x] 表示 在nums[i] - nums[n - 1] 中选 j 个数 or, 能否等于x
        f = [[False] * (mx + 1) for _ in range(k + 1)]
        f[0][0] = True

        suf = [None] * n

        # 下界是 k - 1 的原因是,f 是计算右半部分的,要留 k 个数字给 左半部分
        for i in range(n - 1,k - 1,-1):
            v = nums[i]

            # 遍历到 i 时,f[i] 这一层的值都没更新,用的是 f[i + 1]的值来更新 f[i]
            # 意思是,遍历到 i 时,只是更新 f[i], 不会用 f[i] 去更新别人

            for j in range(k - 1,-1,-1):
                for x,is_true in enumerate(f[j]):
                    if is_true:   # f[i + 1][j][x] = true 
                        f[j + 1][x | v] = True # 更新 f[i][j + 1][x | v] = true 
            
            suf[i] = f[k].copy()
        
        # pre[i][j][x] 表示 在nums[0] - nums[i] 中选 j 个数 or, 能否等于x
        pre = [[False] * (mx + 1) for _ in range(k + 1)]
        pre[0][0] = True

        ans = 0
        for i in range(n - k):
            v = nums[i]
            for j in range(k - 1,-1,-1):
                for x,is_true in enumerate(pre[j]):
                    if is_true:   # pre[i - 1][j][x] = true
                        pre[j + 1][x | v] = True  # 更新 pre[i][j + 1][x | v] = true 
            
            if i < k - 1:
                continue
            
            for x,is_truex in enumerate(pre[k]): # pre[i][k]
                if is_truex:
                    for y,is_truey in enumerate(suf[i + 1]): # f[i + 1][k]
                        if is_truey:
                            # print(x,y)
                            ans = max(ans,x ^ y)
        
        return ans

 

 


http://www.kler.cn/a/508884.html

相关文章:

  • Web自动化:Cypress 测试框架概述
  • 楚慧杯Web
  • 【Go】Go Gorm 详解
  • unity学习18:unity里的 Debug.Log相关
  • 数字小偷:2025年全面防护指南
  • JavaWeb 前端基础 html + CSS 快速入门 | 018
  • 《内网穿透:网络拓展与安全防护的平衡艺术》
  • kubernetes学习-Service(七)
  • 浅谈云计算17 | 分布式存储
  • 【Linux】【Vim】vim编辑器的用法
  • 协同过滤:推荐系统的核心算法详解
  • 会话_JSP_过滤器_监听器_Ajax
  • SimpleHelp远程管理软件存在任意文件读取漏洞(CVE-2024-57727)
  • [STM32 HAL库]串口空闲中断+DMA接收不定长数据
  • 【Pandas】pandas Series apply
  • 电机驱动-标准库和HAL库
  • 分析示例 | Adams_Controls变拓扑分析
  • 【专题一 递归】24. 两两交换链表中的节点
  • 【机器学习:二十六、决策树】
  • 【认识油管头部频道】ep3 “PewDiePie”——游戏内容
  • (RAG系列) FastGPT工作流的http请求模块使用
  • AWS Lambda
  • 【机器学习】鲁棒(健壮)回归-RANSAC(Random Sample Consensus)算法
  • 循环神经网络RNN-数据流动
  • 图数据库 | 18、高可用分布式设计(中)
  • .NET 学习:从基础到进阶的全面指南