AI刷题 209. 小R的子数组全职 | 豆包MarsCode AI 刷题

41 阅读3分钟

问题描述

小R有一个长度为 n 的数组 a,她定义每个子区间 [l, r] 的权值为 a[l] | a[l+1] | ... | a[r],即该区间内所有元素的按位或运算结果。小R非常好奇,在这 n × (n + 1) / 2 个子区间中,究竟有多少种不同的权值。
她希望你能帮她计算一下,所有子区间中的不同权值总共有多少种。

测试样例

样例1:

输入:a = [1, 2, 4]
输出:6

样例2:

输入:a = [5, 3, 8, 1]
输出:8

样例3:

输入:a = [1, 1]
输出:1

样例4:

输入:a = [7, 8, 9, 10, 11]
输出:6

题目分析

问题理解

  1. 子区间:对于一个长度为 n 的数组 a,子区间 [l, r] 表示从索引 l 到索引 r 的所有元素。
  2. 按位或运算:对于子区间 [l, r],其权值为 a[l] | a[l+1] | ... | a[r],即该区间内所有元素的按位或运算结果。
  3. 不同权值的数量:我们需要统计所有可能的子区间的按位或运算结果,并找出这些结果中有多少种不同的值。

数据结构的选择

  • 集合:为了存储不同的权值,我们可以使用集合(set),因为集合会自动去重。

算法步骤

  1. 遍历所有子区间

    • 使用两层循环,外层循环遍历区间的起始位置 l,内层循环遍历区间的结束位置 r
  2. 计算当前子区间的权值

    • 对于每个子区间 [l, r],计算其按位或运算结果,并将其加入集合中。
  3. 统计不同权值的数量

    • 最终集合的大小即为不同权值的数量。

复杂度分析

  • 时间复杂度:由于需要遍历所有子区间,时间复杂度为 O(n^2),其中 n 是数组的长度。
  • 空间复杂度:使用了一个集合来存储不同的权值,空间复杂度为 O(n^2),因为最坏情况下所有子区间的权值都不同。

题解

def solution(a):
    # 使用集合来存储不同的权值
    unique_values = set()
    
    # 遍历所有可能的子区间
    for l in range(len(a)):
        # 初始化当前区间的权值
        current_value = 0
        for r in range(l, len(a)):
            # 计算当前区间的权值
            current_value |= a[r]
            # 将当前区间的权值加入集合
            unique_values.add(current_value)
    
    # 返回不同权值的数量
    return len(unique_values)

if __name__ == '__main__':
    print(solution([1, 2, 4]) == 6)
    print(solution([5, 3, 8, 1]) == 8)
    print(solution([1, 1]) == 1)
    print(solution([7, 8, 9, 10, 11]) == 6)

分析

解法思路

  1. 使用集合存储不同的权值

    • 你使用了 set 来存储不同的权值,这样可以自动去重。
  2. 遍历所有可能的子区间

    • 你使用了两个嵌套的循环来遍历所有可能的子区间 [l, r],其中 l 是区间的起始位置,r 是区间的结束位置。
  3. 计算当前子区间的权值

    • 对于每个子区间 [l, r],你通过按位或运算 current_value |= a[r] 来计算当前区间的权值,并将其加入集合 unique_values 中。
  4. 统计不同权值的数量

    • 最终,集合 unique_values 的大小即为不同权值的数量。