java - 可能的不同子数组
问题描述
获取许多可能的不同子数组,使得它们最多具有给定数量的奇数。
例子:
arr = [2,1,2,1,3]
m = 2.
回答:
10
解释:
- 具有 0 个奇数的不同子数组 = [2]
- 具有 1 个奇数的不同子数组 = [2,1]、[1]、[2,1,2]、[1,2] 和 [3]
- 具有 2 个奇数的不同子数组 = [2,1,2,1], [1,2,1], [2,1,3], [1,3]
所以总共有 10 个可能的不同子数组。
约束:
数组大小最多可包含 1000 个元素,m 的范围可以从 1 到数组大小。
public static int process(List<Integer> arr, int m) {
Set<String> set = new LinkedHashSet<>();
for (int i = 0; i < arr.size(); i++) {
for (int j = i; j < arr.size(); j++) {
int odd = 0;
StringBuilder sb = new StringBuilder();
for (int k1 = i; k1 <= j; k1++) {
if (arr.get(k1) % 2 != 0) {
odd++;
}
sb.append(arr.get(k1) + " ");
}
if (odd <= m) {
set.add(sb.toString());
}
}
}
return set.size();
}
该程序适用于小输入,但由于我有 3 个 for 循环,因此对于大输入失败。解决这个程序的正确方法是什么?
我已经浏览过这篇文章 -查找具有指定奇数个数的子数组的数量,但这里的问题没有考虑不同的子数组。
解决方案
这是一个 O(n^2) 方法:
- 假设元素存储在大小为 n+1 的数组中,位置为 [1....n]
- 让我们相应地修改数组:
A[0]=0
和A[i] = A[i-1] + (A[i]%2==1 ? 1 : 0)
,所以现在 A[i] 存储范围 [0...i] 中的奇数个数 - 注意某些范围内的奇数计数
[i,j]
现在与A[j]-A[i-1]
- 现在只需检查 O(n^2) 中的所有可能范围
- 对于不同的子数组,我们可以使用 Set/Hash 数据结构,但我们需要有效地存储子数组
- 最有效的似乎是散列,我们可以使用一些基 b 和模 m 进行多项式散列,这样
H[0] = 0, H[i] = H[i-1] * b + A[i] % m
如果 a 和 m 是大于最大输入值的素数,它应该可以工作
伪代码:
int res = 0;
for(int i=1; i<=n; i++)
A[i] = A[i-1] + (A[i]%2 == 1);
for(int i=1; i<=n; i++)
for(int j=i; j<=n; j++)
res+=A[j]-A[i-1] <= m;
推荐阅读
- javascript - 如何渲染具有不同组件名称的多个组件?
- python - Spark:如何从 Spark 数据帧行解析和转换 json 字符串
- bash - 如何在motd中获得正确的字符串长度?
- matlab - MATLAB 将 2 个水平数组作为标签和一行添加到表中,而不是 2 列
- c++ - 防止孙子调用其祖父母的方法
- xquery - 如何通过 XQuery 获取所有元素及其属性的列表
- firebase - 如果在哪里使用 Flutter,我不能使用来自 firestore 的 orderBy 查询
- java - 为什么比较法违反总合同?
- node.js - 无法使用 Multer 将图像上传到 NodeJs 服务器
- r - 命令 '/bin/sh -c apt-get update && apt-get install -y r-base' 返回一个非零代码:100