Java 如何在数组中找到大小为k的子数组的总和?
我已经用连续的子数组完成了这项工作,但要找到大小为k的子数组和所有可能的子数组之和是很困难的,我一直面临着死胡同。 请帮帮我Java 如何在数组中找到大小为k的子数组的总和?,java,python,arrays,algorithm,time-complexity,Java,Python,Arrays,Algorithm,Time Complexity,我已经用连续的子数组完成了这项工作,但要找到大小为k的子数组和所有可能的子数组之和是很困难的,我一直面临着死胡同。 请帮帮我 for(int i=0;i<n;i++) { a[i] = sc.nextInt(); } Arrays.sort(a); for(int j=0;j<k;j++) {
for(int i=0;i<n;i++)
{
a[i] = sc.nextInt();
}
Arrays.sort(a);
for(int j=0;j<k;j++)
{
sum = sum + a[j];
}
}
System.out.println(sum);
对于(int i=0;i我们可以这样做:
from itertools import combinations
from heapq import nsmallest
from math import factorial
arr = [2, 3, 2, 1, 1, 1, 1, 1, 2]
k = 3
def optimal(arr, k):
if len(arr) < k:
return 0
k_smallest_elements = nsmallest(k, arr) # n * log(k)
needed_count = k_smallest_elements.count(k_smallest_elements[k - 1])
actual_count = arr.count(k_smallest_elements[k - 1])
# Return actual_count Choose needed_count.
return factorial(actual_count) // factorial(needed_count) // factorial(actual_count - needed_count)
def sub_optimal(arr, k):
if len(arr) < k:
return 0
arr = sorted(arr) # n * log(n)
needed_count = arr[:k].count(arr[k - 1])
actual_count = arr.count(arr[k - 1])
# Return actual_count Choose needed_count.
return factorial(actual_count) // factorial(needed_count) // factorial(actual_count - needed_count)
def brute_force(arr, k):
min_sum = sum(sorted(arr)[:k])
return len([k_len_subset for k_len_subset in combinations(arr, k) if sum(k_len_subset) == min_sum])
count = optimal(arr, k)
assert count == sub_optimal(arr, k) == brute_force(arr, k) # Remove this line in production.
print(count)
来自itertools导入组合的
从heapq导入nsmallest
从数学导入阶乘
arr=[2,3,2,1,1,1,1,1,1,2]
k=3
def最佳(arr,k):
如果len(arr)
一般来说,此问题有两种变体。我将向这两种变体提供解决方案,以帮助未来的读者。您正在为任意子阵列(选择任意K个元素)寻找最小和(其他人可能需要最大和)。另一个常见的类似问题是为任意给定元素的相邻子阵列找到最小或最大和(拾取k个相邻图元)或任意长度
任意子阵列
您可以在O(n logn)时间内解决此问题。对子数组进行排序,然后对排序数组中的最后k个元素求和
通过排序,最大的元素位于已排序数组的末尾。通过对最大的元素求和,可以得到最大的和
这就是您的代码似乎要做的
连续子阵列
K相邻元素
通过计算数组中滑动窗口的总和,可以在O(n)时间内解决此问题。第一个窗口由索引为0..(k-1)的元素和最后一个元素(n-2)…n组成
计算第一个窗口的和
对于每个附加窗口:
- 该窗口的总和是前一个窗口的总和,减去刚刚掉出来的元素(窗口开始下方的数组元素),然后添加刚刚包含的元素(刚刚包含在当前窗口中的数组元素)
- 取当前窗口总和的最小值或最大值(根据需要)和迄今为止记录的最高总和。这是您当前的最低值或最高值
处理最后一个窗口后,您的min或max变量表示最低或最高总和(视情况而定)。如果需要,您还可以在max更改时记录该窗口的起始索引
任意数量的相邻元素
有趣的是,任意长度的子阵列的最高和也可以在O(n)时间内使用一种聪明的方法来计算。大多数情况下,诸如“获取数组中长度K的所有非连续子序列”或“将数组拆分为K个子阵列”之类的问题有一个额外的条件,你应该考虑它找到一种方法。
这里,您的方法是按递增顺序对数组排序,并计算第一个K元素的和
sm = 0
k = 3
arr = [2, 5, 9, 7, 6, 3]
arr.sort()
for i in range(k):
sm += arr[i]
print(sm)
选择一种语言。滥发语言标签会招致嘲笑和否决票。同时向我们展示你为实现目标所做的努力。这不是语言问题,这是算法问题。语言标签无关紧要。@JonathanLeffler我想我可以得到解决方案,我想说任何语言解决方案都可以接受。@Serge是的,请帮我做算法谢谢你的解决方案,但这不是我想要的。你已经对连续项进行了分组,但对非连续项又如何呢。例如:[2,7,3]=12。它不这样做。@knock_,那么它们不是“子数组”。它们是“子序列”.对此我很抱歉…是的,接下来…非常感谢@knoch_out…我能解释一下吗?我对python和时间复杂性有点熟悉,更大的列表会花费很多时间吗?这样做是O(n!/(n-k)!;。当n大,k比n小时,速度相当慢。有优化的方法吗?!@EricJ