LeetCode 题解工作台

划分数组得到最小的值之和

给你两个数组 nums 和 andValues ,长度分别为 n 和 m 。 数组的 值 等于该数组的 最后一个 元素。 你需要将 nums 划分为 m 个 不相交的连续 子数组 ,对于第 i th 个子数组 [l i , r i ] ,子数组元素的按位 AND 运算结果等于 andValues[i…

category

6

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

困难 · 状态·转移·动态规划

bolt

答案摘要

我们设计一个函数 $dfs(i, j, a)$,表示从第 个元素开始,当前已经划分了 个子数组,且当前待划分的子数组的按位与结果为 的情况下,所能得到的可能的最小子数组值之和。那么答案就是 $dfs(0, 0, -1)$。 函数 $dfs(i, j, a)$ 的执行过程如下:

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你两个数组 numsandValues,长度分别为 nm

数组的 等于该数组的 最后一个 元素。

你需要将 nums 划分为 m不相交的连续 子数组,对于第 ith 个子数组 [li, ri],子数组元素的按位 AND 运算结果等于 andValues[i],换句话说,对所有的 1 <= i <= mnums[li] & nums[li + 1] & ... & nums[ri] == andValues[i] ,其中 & 表示按位 AND 运算符。

返回将 nums 划分为 m 个子数组所能得到的可能的 最小 子数组 之和。如果无法完成这样的划分,则返回 -1

 

示例 1:

输入: nums = [1,4,3,3,2], andValues = [0,3,3,2]

输出: 12

解释:

唯一可能的划分方法为:

  1. [1,4] 因为 1 & 4 == 0
  2. [3] 因为单元素子数组的按位 AND 结果就是该元素本身
  3. [3] 因为单元素子数组的按位 AND 结果就是该元素本身
  4. [2] 因为单元素子数组的按位 AND 结果就是该元素本身

这些子数组的值之和为 4 + 3 + 3 + 2 = 12

示例 2:

输入: nums = [2,3,5,7,7,7,5], andValues = [0,7,5]

输出: 17

解释:

划分 nums 的三种方式为:

  1. [[2,3,5],[7,7,7],[5]] 其中子数组的值之和为 5 + 7 + 5 = 17
  2. [[2,3,5,7],[7,7],[5]] 其中子数组的值之和为 7 + 7 + 5 = 19
  3. [[2,3,5,7,7],[7],[5]] 其中子数组的值之和为 7 + 7 + 5 = 19

子数组值之和的最小可能值为 17

示例 3:

输入: nums = [1,2,3,4], andValues = [2]

输出: -1

解释:

整个数组 nums 的按位 AND 结果为 0。由于无法将 nums 划分为单个子数组使得元素的按位 AND 结果为 2,因此返回 -1

 

提示:

  • 1 <= n == nums.length <= 104
  • 1 <= m == andValues.length <= min(n, 10)
  • 1 <= nums[i] < 105
  • 0 <= andValues[j] < 105
lightbulb

解题思路

方法一:记忆化搜索

我们设计一个函数 dfs(i,j,a)dfs(i, j, a),表示从第 ii 个元素开始,当前已经划分了 jj 个子数组,且当前待划分的子数组的按位与结果为 aa 的情况下,所能得到的可能的最小子数组值之和。那么答案就是 dfs(0,0,1)dfs(0, 0, -1)

函数 dfs(i,j,a)dfs(i, j, a) 的执行过程如下:

  • 如果 ni<mjn - i < m - j,那么说明剩下的元素不足以划分出 mjm - j 个子数组,返回 ++\infty
  • 如果 j=mj = m,那么说明已经划分出了 mm 个子数组,此时判断 i=ni = n 是否成立,如果成立返回 00,否则返回 ++\infty
  • 否则,我们将 aanums[i]nums[i] 进行按位与操作,得到新的 aa。如果 a<andValues[j]a < andValues[j],那么说明当前待划分的子数组的按位与结果不满足要求,返回 ++\infty。否则,我们有两种选择:
    • 不划分当前元素,即 dfs(i+1,j,a)dfs(i + 1, j, a)
    • 划分当前元素,即 dfs(i+1,j+1,1)+nums[i]dfs(i + 1, j + 1, -1) + nums[i]
  • 返回上述两种选择的最小值。

为了避免重复计算,我们使用记忆化搜索的方法,将 dfs(i,j,a)dfs(i, j, a) 的结果存储在一个哈希表中。

时间复杂度 O(n×m×logM)O(n \times m \times \log M),空间复杂度 O(n×m×logM)O(n \times m \times \log M)。其中 nnmm 分别是数组 numsnumsandValuesandValues 的长度;而 MM 是数组 numsnums 中的最大值,本题中 M105M \leq 10^5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
    def minimumValueSum(self, nums: List[int], andValues: List[int]) -> int:
        @cache
        def dfs(i: int, j: int, a: int) -> int:
            if n - i < m - j:
                return inf
            if j == m:
                return 0 if i == n else inf
            a &= nums[i]
            if a < andValues[j]:
                return inf
            ans = dfs(i + 1, j, a)
            if a == andValues[j]:
                ans = min(ans, dfs(i + 1, j + 1, -1) + nums[i])
            return ans

        n, m = len(nums), len(andValues)
        ans = dfs(0, 0, -1)
        return ans if ans < inf else -1
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Candidate is familiar with dynamic programming for state transitions.

  • question_mark

    Candidate understands bitwise operations and how they apply to subarrays.

  • question_mark

    Candidate optimizes the solution by avoiding redundant calculations and efficiently updating states.

warning

常见陷阱

外企场景
  • error

    Not handling edge cases where a valid division is impossible, returning -1 in such cases.

  • error

    Overcomplicating the bitwise AND computation by recalculating for each subarray repeatedly.

  • error

    Missing an efficient way to manage dynamic programming state transitions, leading to redundant operations.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Consider variations where the number of subarrays is increased, making it necessary to optimize the DP approach.

  • arrow_right_alt

    Differentiate the problem by changing the bitwise operation (e.g., OR instead of AND) and observe the impact on the solution.

  • arrow_right_alt

    Change the problem constraints, such as limiting the size of nums or andValues, to explore how that affects the approach.

help

常见问题

外企场景

划分数组得到最小的值之和题解:状态·转移·动态规划 | LeetCode #3117 困难