从1-9找到k个数字组合和为n

来源:互联网 发布:航天数据股份有限公司 编辑:程序博客网 时间:2024/05/22 07:01

题目来自LeetCode Combination Sum III:在1-9数字中,不重复地选择k个数字,使其和为n。

使用backtracking方法,即先试第k个,然后改变第k-1个再试第k个,再改变第k-2个再继续试……


我们知道需要用到递归,但是要把递归函数设计成什么样呢,

首先确定结束递归的条件,当结果数组的元素个数为k,和为n时,结束递归,

但是不一定只有这一个答案,所以递归函数的最外层还是应该有for循环把全部元素遍历一遍,

遍历时有些情况也是明确不用继续下去的,比如超过k个元素或者和超过n时。


最后思路是先加入1,然后如果不到k个元素就加入2,以此类推,直到够了k个元素时for循环第k个元素,

如果和小于n,继续试第k个元素,

如果等于n就把这个结果加入结果集,继续第k-1位的遍历,

如果大于n就不继续进行对第k个元素的试探,转而试探第k-1个元素。

需要注意的地方是要想到每次递归时传入的n是改变的,要想到试探完一个元素之后就把它弹出。

每一个尝试都只考虑自己是否满足条件。满足就加入结果集,k不满足就试图增加元素,n不满足就换掉最后一位元素或者更换之前的元素继续,直到所有可能遍历结束。


class Solution {public:    void trycmb(vector<vector<int>>& res, vector<int> cur, int k, int n) //结果集res,目前的尝试cur    {        if (cur.size() == k && n == 0)//每次递归传入的n都是减去了尝试的组合cur的前面元素的和,只留下最后一个位置的期望的大小        {             res.push_back(cur);            return;        }        if (cur.size() < k)         {            for (int i = cur.empty() ? 1 : cur.back() + 1; i <= 9; i++)//尝试当前组合cur的最后一个元素的大小             {                if (i>n)                     break;                cur.push_back(i);                trycmb(res, cur, k, n - i);                cur.pop_back();//如果这个值试过了,不管行不行都要遍历到下一个            }        }    }    vector<vector<int>> combinationSum3(int k, int n)     {        vector<vector<int>> res;        vector<int> cur;        trycmb(res, cur, k, n);        return res;    }};

阅读全文
0 0
原创粉丝点击