第 21 题(数组)
2010 年中兴面试题
编程求解:
输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数,
使其和等于 m ,要求将其中所有的可能组合列出来.
我的思路:
从小到大 依次拼凑 后面选的数字 必须比前面大 保证不重复
如: n = 4 m = 8
1 2 3 4 超过8 去掉最后一个数 导数第二个数加一
1 2 4 小于8 最后一个数等于 4 去掉最后一个数 导数第二个数加一
1 3 4 符合 输出 最后一个数等于 4 去掉最后一个数 导数第二个数加一
1 4 小于8 最后一个数等于 4 去掉最后一个数 导数第二个数加一
2 3 小于8
2 3 4 超过8 去掉最后一个数 导数第二个数加一
2 4 小于8 最后一个数等于 4 去掉最后一个数 导数第二个数加一
......
代码:
/*第 21 题(数组)
2010 年中兴面试题
编程求解:
输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数,
使其和等于 m ,要求将其中所有的可能组合列出来.
start time = 15:55
end time = 17:03*/#include
using namespacestd;int FindCombine(int n, intm)
{int method = 0; //一共有多少方法
if(m <= 0)
{return 0;
}else{int record[100]; //存储组合当前的取值
for(int i = 0; i < 100; i++)
{
record[i]= i + 1;
}int num = 0; //组合中数字的个数
int sum = 0; //组合中数字加起来的和
while(sum
{
sum+=record[num];
num++;if(sum ==m)
{
method++;
printf("组合%d:", method);for(int i = 0; i < num; i++)
{
printf("%d", record[i]);
}
printf("\n");if(num == 1)
{returnmethod;
}
}if((sum >= m) || (sum < m && record[num - 1] == n && num >= 2)) //如果大小超过m 或者 最后一个数字大小等于n 更新record
{
num--;
sum-=record[num];
num--;
sum-=record[num];if(record[num] <=n)
{
record[num]++;for(int i = 1; i <= n - record[num]; i++)
{
record[i+ num] = record[num] +i;
}
}
}else if(sum < m && record[num - 1] == n && num == 1)
{returnmethod;
}
}
}
}intmain()
{int w = FindCombine(50, 100);return 0;
}
惯例上网找别人的方法, 一看我就郁闷了, 居然可以用动态规划, 我的算法算是白学了, 到用的时候一点都想不起来。
http://blog.sina.com.cn/s/blog_7571423b01016707.html 里有个详细的分析
http://www.cnblogs.com/freewater/archive/2012/07/16/2593218.html 里有非常精简的代码
vectorfactors;void findFactor2(int sum,intn){if(sum<0||n<0)return;if(sum==0){for(vector::iterator iter=factors.begin();iter!=factors.end();++iter){
cout<
}
cout<
}
factors.push_back(n);//典型的01背包问题
findFactor2(sum-n,n-1);//放n,n-1个数填满sum-n
factors.pop_back();
findFactor2(sum,n-1);//不放n,n-1个数填满sum
}
该博客主要介绍了如何使用Python解决一道中兴面试题:输入两个整数n和m,找出所有从数列1到n中和为m的组合。博主通过递归和循环实现,同时提到了动态规划的解决方案。

4485

被折叠的 条评论
为什么被折叠?



