You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已知子集大小与连续数组的子集和问题高效求解方案

高效求解固定大小的连续整数子集和问题

针对输入为1到2000的连续整数、要求返回所有大小为k且和为目标值S的子集的问题,我们可以利用数学剪枝+递归回溯的方法大幅提升效率,避免常规子集和算法的冗余计算。

核心思路

  1. 先判断解的存在性:

    • 大小为k的子集的最小和:min_sum = k*(k+1)//2(取前k个最小数)
    • 大小为k的子集的最大和:max_sum = k*(2*2000 - k +1)//2(取后k个最大数)
    • 若目标和S不在[min_sum, max_sum]范围内,直接返回空列表。
  2. 递归回溯+剪枝优化:

    • 递归时从当前位置开始选择下一个数(避免生成重复子集,比如[1,2]和[2,1]视为同一个子集)
    • 每一步选择数i时,提前计算:
      • 剩余k-1个数的最小可能和(从i+1开始取连续k-1个数),若该值大于剩余需要的和,直接跳过后续更大的数
      • 剩余k-1个数的最大可能和(从2000往前取k-1个数),若该值小于剩余需要的和,直接跳过当前数

Python 示例代码

def find_k_subsets(k, target_sum, max_num=2000):
    result = []
    # 计算最小和与最大和,判断是否存在解
    min_sum = k * (k + 1) // 2
    max_sum = k * (2 * max_num - k + 1) // 2
    if target_sum < min_sum or target_sum > max_sum:
        return result
    
    def backtrack(start, remaining_k, remaining_sum, path):
        if remaining_k == 0:
            if remaining_sum == 0:
                result.append(path.copy())
            return
        # 遍历从start到max_num的数
        for i in range(start, max_num + 1):
            # 如果当前数已经大于剩余需要的和,后面的数更大,直接break
            if i > remaining_sum:
                break
            # 计算剩余k-1个数的最小可能和:(i+1)+(i+2)+...+(i+remaining_k-1)
            min_remaining = (remaining_k - 1) * (2 * i + remaining_k) // 2
            if min_remaining > remaining_sum - i:
                break  # 即使选后面最小的数也不够,不用继续遍历更大的i
            # 计算剩余k-1个数的最大可能和:max_num + (max_num-1) + ... + (max_num - remaining_k +2)
            max_remaining = (remaining_k - 1) * (2 * max_num - remaining_k + 2) // 2
            if max_remaining < remaining_sum - i:
                continue  # 即使选后面最大的数也不够,跳过当前i
            # 递归
            path.append(i)
            backtrack(i + 1, remaining_k - 1, remaining_sum - i, path)
            path.pop()
    
    backtrack(1, k, target_sum, [])
    return result

# 示例调用:寻找大小为3,和为6的子集
if __name__ == "__main__":
    subsets = find_k_subsets(3, 6)
    print(subsets)  # 输出: [[1,2,3]]

效率说明

  • 由于加入了严格的剪枝条件,该算法不会遍历所有可能的组合,尤其是当k较小或目标和接近边界时,速度会非常快。
  • 对于k较大的情况(比如k=1000),解的数量本身会很少(甚至唯一),算法也能快速定位。

内容的提问来源于stack exchange,提问作者Fanfer123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:15:37