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

回溯法实现组合问题:返回列表元素为空的原因分析

回溯法组合问题:返回空集合的原因及修复

我正在学习回溯法,遇到如下问题:给定两个整数n和k,返回从范围[1, n]中选取k个数的所有可能组合,返回顺序不限。用n=4、k=2测试时,编写的C#代码返回的list包含6个元素(数量正确),但每个元素都是空集合。调试时能找到正确组合,但最终返回的列表元素为空。

相关代码如下:

IList<IList<int>> Combine(int n, int k)
{
    IList<IList<int>> list = new List<IList<int>>();
    IList<int> listComb = new List<int>();
    backtrack(1, n, k, list, listComb);

    return list;
}
void backtrack(int start,int end,int k,IList<IList<int>> list,IList<int> oneComb)
{
    if (oneComb.Count == k)
    {
        list.Add(oneComb);
        return;
    }

    for(int i= start; i <= end; i++)
    {
        oneComb.Add(i);
        backtrack(i + 1, end, k, list, oneComb);
        oneComb.RemoveAt(oneComb.Count-1);
    }
}

Combine(4, 2);

调试时可看到正确组合(截图如下):
调试截图

问题根源

你在回溯过程中始终复用同一个oneComb集合对象。当执行list.Add(oneComb)时,只是将该集合的引用添加到结果列表中,而非创建一个独立的副本。后续的RemoveAt操作会修改这个共享的集合,最终所有引用指向的都是被清空后的集合,因此返回的结果全是空集合。

修复方案

当满足oneComb.Count == k的条件时,添加集合的副本到结果列表,这样后续的回溯操作不会影响已保存的组合。修改backtrack方法中的判断逻辑即可:

if (oneComb.Count == k)
{
    list.Add(new List<int>(oneComb)); // 创建副本添加
    return;
}

修改后的完整代码

IList<IList<int>> Combine(int n, int k)
{
    IList<IList<int>> list = new List<IList<int>>();
    IList<int> listComb = new List<int>();
    backtrack(1, n, k, list, listComb);

    return list;
}
void backtrack(int start,int end,int k,IList<IList<int>> list,IList<int> oneComb)
{
    if (oneComb.Count == k)
    {
        list.Add(new List<int>(oneComb));
        return;
    }

    for(int i= start; i <= end; i++)
    {
        oneComb.Add(i);
        backtrack(i + 1, end, k, list, oneComb);
        oneComb.RemoveAt(oneComb.Count-1);
    }
}

这样修改后,返回的结果列表中会包含6个正确的非空组合:[1,2]、[1,3]、[1,4]、[2,3]、[2,4]、[3,4]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:20:28