Combination Sum III C#
2015-08-24 09:16
525 查看
Find all possible combinations of k numbers that add up to a numbern, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.
Ensure that numbers within the set are sorted in ascending order.
Example 1:
Input: k = 3, n = 7
Output:
Example 2:
Input: k = 3, n = 9
Output:
题意:将一个正整数n拆分成k个数字的累加和,k个数字互不相同且按照升序排列。返回满足条件的k个数字的所有组合。
解析:首先 分析该问题的隐藏条件:因为只能分解成9以内的数字组合,且每个数字都只能出现一次,所以可以,根据抽屉原则,k最大为9,n最大为1+2+3+..+9 = 45,且根据题意k,n都是正整数,还有一个隐藏条件是n / k <= 9;以上条件是这个问题的隐藏条件。
其次,该问题的tag是backtrackings,回溯法的应用,回溯法解决问题的思路是:d(1)作为有可能解决问题的满足要求的第一步可能解,在d(1)的条件下得到有可能解决问题的满足条件的第二步解的解d(2),依次类推,当推到d(N)时出现了不能继续后推得到满足跳进的下一步解时回归到上一步d(N-1),此时d(N-1)换另一个可能解,继续后推,直到所有的d(N-1)的可能解都无法后推出解决此问题的解时,回归到d(N-2)步。
针对这个问题,使用回溯法,要解决两个问题,第一:n分解出的k个数字是按照升序排列的。第二:当 i 进入解集后无法推出有效解的时候,如何回溯到 i 并将代替 i 的下一个可能解加入解集。
代码实现:
Ensure that numbers within the set are sorted in ascending order.
Example 1:
Input: k = 3, n = 7
Output:
[[1,2,4]]
Example 2:
Input: k = 3, n = 9
Output:
[[1,2,6], [1,3,5], [2,3,4]
题意:将一个正整数n拆分成k个数字的累加和,k个数字互不相同且按照升序排列。返回满足条件的k个数字的所有组合。
解析:首先 分析该问题的隐藏条件:因为只能分解成9以内的数字组合,且每个数字都只能出现一次,所以可以,根据抽屉原则,k最大为9,n最大为1+2+3+..+9 = 45,且根据题意k,n都是正整数,还有一个隐藏条件是n / k <= 9;以上条件是这个问题的隐藏条件。
其次,该问题的tag是backtrackings,回溯法的应用,回溯法解决问题的思路是:d(1)作为有可能解决问题的满足要求的第一步可能解,在d(1)的条件下得到有可能解决问题的满足条件的第二步解的解d(2),依次类推,当推到d(N)时出现了不能继续后推得到满足跳进的下一步解时回归到上一步d(N-1),此时d(N-1)换另一个可能解,继续后推,直到所有的d(N-1)的可能解都无法后推出解决此问题的解时,回归到d(N-2)步。
针对这个问题,使用回溯法,要解决两个问题,第一:n分解出的k个数字是按照升序排列的。第二:当 i 进入解集后无法推出有效解的时候,如何回溯到 i 并将代替 i 的下一个可能解加入解集。
代码实现:
public class Solution { public List<List<int>> CombinationSum3(int k, int n) { List<List<int>> ret = new List<List<int>>(); Stack<int> tmp = new Stack<int>(); // 使用栈的特性来将可能解加入到解集中,并在完成这一可能解的所有后推解的验证后更换下一可能解。 if (k == 0 || n == 0 || n / k > 9 || k > 9 || n >45) return ret; help(ret, tmp, 1, k, n); return ret; } public void help(List<List<int>> ret, Stack<int> tmp, int start, int k, int n) { if (k == 0 && n == 0) { ret.Add(new List<int>(tmp.Reverse())); // C#中的栈转换成列表是逆序的,所以也需要逆转一下,这也是使算法变慢的一个主要原因。 return; } for (int i = start; i <= 9 && k >= 1 && n >= i; i++) // k , n的下限设置不是必须的,但是加上后会有效的减少递归层数。 { tmp.Push(i); help(ret, tmp, i + 1, k - 1, n - i); tmp.Pop(); } } }
相关文章推荐
- c#调用COM组件
- C#实现把指定数据写入串口
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#使用加边法计算行列式的值
- C#实现多线程的同步方法实例分析
- C#中尾递归的使用、优化及编译器优化
- C#通用邮件发送类分享
- C#中this的用法集锦
- C#.NET获取拨号连接的宽带连接方法
- C#实现AddRange为数组添加多个元素的方法
- C#中Equality和Identity浅析
- C#生成饼形图及添加文字说明实例代码
- C#判等对象是否相等的方法汇总
- C#简单的向量用法实例教程
- C#实现基于链表的内存记事本实例
- C#托管堆对象实例包含内容分析
- C#实现按照指定长度在数字前补0方法小结
- C# 通过 inline-asm 解决嵌入x86汇编
- C#虚方法的声明和使用实例教程