算法笔记(DFS)

问题来自牛客

输入两个整数 n 和 m,从数列1,2,3…….n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来 。

解决思路:

1-n找到数字之和等于m,那么如果我先找到一个数1,剩下的任务就是在2~m-1 找到求和等于m-1 就够了。那如果找到第2个数2 求和小于(找到的1+2求和为3)m,接下来找3,继续这样往下找,如果求和大于m则不合适,说明组合不合理,这时候需要退回,说明1-2 组合不合适,这时需要尝试新的组合比如1-3反复如此直到计算结束。

m=5,n=5 为例,

  • 开始,1入栈,接下来在2-5之间找到数字之和为4(m-1=5-1)
  • 2入栈,接下来在3-5 之间找到数字子和为2的数字,因为接下来的数字至少都等于3,所以肯定找不到,于是2出栈
  • 3进栈,接下来的任务是在4-5 之间找到数字使得其和为1,显然找不到,退栈。
  • 4进栈,这时候满足求和为5,于是输出。不用直接到5了,因为5,m就为-1了。于是1退栈。
  • 2进栈,这时候需要在3-5 之间找到数字使得和为3。
  • 3进栈,这时候找到,直接打印,退栈(2,3)。
  • 3进栈,需要在4-5 之间找到能够使得和为(2),明显找不到,退栈。剩下依次。
  • 5入栈,接下来需要在剩下的数字中找到0,打印结果。

下面的代码来自牛客,作者没有注明,无法引用(仅修改打印部分)。

#include <iostream>
#include <vector>
using namespace std;
void help(int n,int m,vector<int> &v,int begin)
{
    if(m == 0)
    {
        for(auto i:v)
        {
            cout<<i<<" ";
        }
        cout<<"\n";
    }
    for(int i=begin;i<=m&&i<=n;i++)
    {
        v.push_back(i);
        help(n,m-i,v,i+1);
        v.pop_back();
    }

}
int main() {
    int n = 5;
    int m = 5;
    vector<int> v;
//    cin>>n>>m;
    help(n,m,v,1);
    return 0;
}

代码中vector作为栈使用用来存储可用的数据,打印逻辑是碰到m为0的时候打印。
下面是Python实现:

def get_sum(n,m,l,begin_num):
    if m == 0:
        for i in l:
            print(i,end=" ")
        print()

    else:
        for i in range(begin_num,m+1):
            if i<=m and i<=n:
                l.append(i)
                get_sum(n,m-i,l,i+1)
                l.pop()

def main():
    # n,m = input().split()
    # n = eval(n)
    # m = eval(m)
    m = 8
    n = 10
    get_sum(n,m,[],1)
if __name__ == '__main__':
    main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值