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

求数组元素和等于目标值的组合:伪代码及C#实现咨询

找出数组中所有和为目标值的元素组合

Hey Joe, 你碰到的是经典的子集和问题,不过你需要的是找出所有能相加等于目标值的元素组合,而不只是判断有没有这样的组合。下面我给你梳理伪代码思路和对应的C#实现,刚好适配你说的1到65的数组场景~

伪代码思路(回溯法)

回溯法是解决这类“找所有组合”问题的常用方式,核心是枚举所有可能的选择(选当前元素/不选当前元素),并通过剪枝减少不必要的计算:

// 输入:待处理数组arr,目标和target
// 输出:所有和为target的元素组合列表

function findSubsetSums(arr, target):
    将arr按升序排序(方便后续剪枝,遇到大于剩余目标值的元素直接停止)
    初始化结果集合result = []
    
    // 递归回溯函数:参数为当前处理索引、当前组合、剩余需要凑的数值
    function backtrack(currentIndex, currentCombination, remainingTarget):
        // 终止条件1:剩余目标值为0,找到有效组合
        if remainingTarget == 0:
            将currentCombination的副本加入result
            return
        // 终止条件2:剩余目标值为负,或者索引越界,直接返回
        if remainingTarget < 0 or currentIndex >= arr.length:
            return
        
        // 选择1:将当前元素加入组合,继续处理下一个元素
        把arr[currentIndex]加入currentCombination
        backtrack(currentIndex + 1, currentCombination, remainingTarget - arr[currentIndex])
        
        // 回溯:移除刚加入的元素,尝试另一种选择
        从currentCombination中移除arr[currentIndex]
        
        // 选择2:不选当前元素,直接处理下一个元素
        backtrack(currentIndex + 1, currentCombination, remainingTarget)
    
    // 启动回溯
    backtrack(0, [], target)
    返回result

C# 完整实现代码

下面是针对你的场景的可运行C#代码,包含生成1-65数组、计算目标值10的所有组合的逻辑:

using System;
using System.Collections.Generic;
using System.Linq;

class SubsetSumFinder
{
    static void Main(string[] args)
    {
        // 生成1到65的数组
        int[] numberArray = Enumerable.Range(1, 65).ToArray();
        int targetSum = 10;
        
        // 获取所有符合条件的组合
        List<List<int>> validCombinations = FindAllSubsetSums(numberArray, targetSum);
        
        // 打印结果
        Console.WriteLine($"所有和为{targetSum}的元素组合:");
        foreach (var combo in validCombinations)
        {
            Console.WriteLine($"{string.Join(" + ", combo)} = {targetSum}");
        }
    }
    
    static List<List<int>> FindAllSubsetSums(int[] arr, int target)
    {
        // 排序数组,优化剪枝效率
        Array.Sort(arr);
        List<List<int>> result = new List<List<int>>();
        
        // 调用回溯函数
        Backtrack(arr, target, 0, new List<int>(), result);
        
        return result;
    }
    
    static void Backtrack(int[] arr, int remainingTarget, int currentIndex, List<int> currentCombo, List<List<int>> result)
    {
        // 找到有效组合,加入结果集
        if (remainingTarget == 0)
        {
            result.Add(new List<int>(currentCombo));
            return;
        }
        
        // 剪枝:剩余目标值为负或索引越界,直接终止
        if (remainingTarget < 0 || currentIndex >= arr.Length)
        {
            return;
        }
        
        // 选择当前元素,递归处理下一个索引
        currentCombo.Add(arr[currentIndex]);
        Backtrack(arr, remainingTarget - arr[currentIndex], currentIndex + 1, currentCombo, result);
        
        // 回溯:移除当前元素,尝试不选它的分支
        currentCombo.RemoveAt(currentCombo.Count - 1);
        
        // (可选)如果数组有重复元素,这里可以跳过重复值避免重复组合
        // while (currentIndex + 1 < arr.Length && arr[currentIndex] == arr[currentIndex + 1])
        // {
        //     currentIndex++;
        // }
        
        // 不选择当前元素,递归处理下一个索引
        Backtrack(arr, remainingTarget, currentIndex + 1, currentCombo, result);
    }
}

额外说明

  • 剪枝优化:因为数组已经排序,当处理到某个元素大于剩余目标值时,后续所有元素都会更大,完全可以提前终止该分支的递归,这会大幅提升效率(比如目标值是10时,处理到11就直接停止,不用再遍历后面的元素)。
  • 时间复杂度:理论上是O(2^n),但实际因剪枝优化会远低于这个数值,尤其是目标值较小时,像你例子中的目标值10,运行速度会非常快。
  • 重复元素处理:如果你的数组存在重复元素,只需解开代码中注释的去重逻辑,就能避免生成重复的组合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:46:59