2024-12-02:划分数组得到最小的值之和。用go语言,你有两个数组,nums 和 andValues,它们的长度分别为 n
【摘要】 2024-12-02:划分数组得到最小的值之和。用go语言,你有两个数组,nums 和 andValues,它们的长度分别为 n 和 m。定义数组的“值”为其最后一个元素。你的任务是将 nums 划分为 m 个不重叠的连续子数组。对于第 i 个子数组 [li, ri],该子数组的所有元素通过按位与运算后,结果必须等于 andValues[i]。换句话说,对于所有的 1 <= i <= m,应...
2024-12-02:划分数组得到最小的值之和。用go语言,你有两个数组,nums 和 andValues,它们的长度分别为 n 和 m。定义数组的“值”为其最后一个元素。
你的任务是将 nums 划分为 m 个不重叠的连续子数组。对于第 i 个子数组 [li, ri],该子数组的所有元素通过按位与运算后,结果必须等于 andValues[i]。换句话说,对于所有的 1 <= i <= m,应该满足 nums[li] & nums[li + 1] & ... & nums[ri] == andValues[i],其中 & 表示按位与运算符。
你的目标是返回将 nums 划分为 m 个子数组时,得到的可能的最小子数组值之和。如果无法完成这样的划分,则返回 -1。
提示:
1 <= n == nums.length <= 10000。
1 <= m == andValues.length <= min(n, 10)。
1 <= nums[i] < 100000。
0 <= andValues[j] < 100000。
输入: 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。
答案2024-12-02:
[chatgpt](https://chatbotsplace.com/?rc=nnNWSCJ7EP)
题目来自leetcode3117。
# 大体步骤如下:
1.定义常量 INF 作为无穷大的表示,为 (1 << 20) - 1。
2.初始化 nums 和 andValues 的长度 n 和 m。
3.创建 memo 数组,大小为 n*m,用于记忆化搜索过程中的中间结果。
4.定义递归函数 dfs(i, j, cur int) int,用于计算最小子数组值之和,函数体如下:
- 计算当前状态的键值 key 以在 memo 中保存中间结果。
- 检查结束条件:如果 i 和 j 都达到末尾则返回 0,如果其中一个到达末尾则返回 INF。
- 检查 memo 中是否已有当前状态结果,若有则直接返回。
- 对当前的 cur 进行按位与操作并检查是否符合条件,若不符合则返回 INF。
- 递归调用 dfs 处理两种情况:不选当前元素和选取当前元素。
- 更新 memo 并返回结果。
5.调用 dfs(0, 0, INF) 启动递归计算最小值之和,并将结果存储在 res 中。
6.检查 res 是否小于INF,如果是则返回 res,否则返回 -1。
总的时间复杂度为 O(n*m)。
总的额外空间复杂度为 O(n*m)。
# Go完整代码如下:
```go
package main
import (
"fmt"
)
func minimumValueSum(nums []int, andValues []int) int {
const INF = (1 << 20) - 1
n := len(nums)
m := len(andValues)
memo := make([]map[int]int, n*m)
for i := range memo {
memo[i] = make(map[int]int)
}
var dfs func(i, j, cur int) int
dfs = func(i, j, cur int) int {
key := i*m + j
if i == n && j == m {
return 0
}
if i == n || j == m {
return INF
}
if val, ok := memo[key][cur]; ok {
return val
}
cur &= nums[i]
if cur&andValues[j] < andValues[j] {
return INF
}
res := dfs(i+1, j, cur)
if cur == andValues[j] {
res = min(res, dfs(i+1, j+1, INF)+nums[i])
}
memo[key][cur] = res
return res
}
res := dfs(0, 0, INF)
if res < INF {
return res
}
return -1
}
func main() {
nums := []int{1, 4, 3, 3, 2}
andValues := []int{0, 3, 3, 2}
fmt.Println(minimumValueSum(nums, andValues))
}
```
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/382912dfd771463089123d29f0ffdd96.png)
# Rust完整代码如下:
```rust
use std::collections::HashMap;
const INF: i32 = (1 << 20) - 1;
fn minimum_value_sum(nums: &[i32], and_values: &[i32]) -> i32 {
let n = nums.len();
let m = and_values.len();
let mut memo = vec![HashMap::new(); n * m];
fn dfs(
i: usize,
j: usize,
cur: i32,
nums: &[i32],
and_values: &[i32],
memo: &mut Vec<HashMap<i32, i32>>,
) -> i32 {
if i == nums.len() && j == and_values.len() {
return 0;
}
if i == nums.len() || j == and_values.len() {
return INF;
}
let key = i * and_values.len() + j;
if let Some(&val) = memo[key].get(&cur) {
return val;
}
let new_cur = cur & nums[i];
if new_cur & and_values[j] < and_values[j] {
return INF;
}
let mut res = dfs(i + 1, j, new_cur, nums, and_values, memo);
if new_cur == and_values[j] {
res = res.min(dfs(i + 1, j + 1, INF, nums, and_values, memo) + nums[i]);
}
memo[key].insert(cur, res);
res
}
let res = dfs(0, 0, INF, nums, and_values, &mut memo);
if res < INF {
res
} else {
-1
}
}
fn main() {
let nums = vec![1, 4, 3, 3, 2];
let and_values = vec![0, 3, 3, 2];
println!("{}", minimum_value_sum(&nums, &and_values));
}
```
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3663d29062a64c7180acb62d8a2715dc.png)
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)