对一道算法面试题的理解
2012-04-12 18:32
260 查看
这是一道很简单的算法题,读者若是抱着学习知识的态度,请打住!该文章只是简单的记录自己学习心得而已!题目是求出1-100内所有相加之和等于100的组合,所有组合不能重复,组合内的数字也不能重复!
下面是谈谈我对一道算法面试题的理解:
我们可以采用由前往后的方法来组合所有数字,以达到相加之和等于100的目的,可以试着推测,第一次的数字由1开始,一次往后推进,当推进到某一个数字时,他们之间的所有数之和大于100,于是我们将最后这个数丢弃,把倒数第二个数往前推进一位,可想而知,这时的所有数之和一定小于或者等于100,并且,在所剩下的数中一定有某个数
与前面所有数之和相加等于100,由于所有数不能重复,所以我们可以认为只要以前面的50个数字往后推进,后面所有组合都会被包含,所以第一个数,我们选择1-50.(因为50只有和50才能匹配,所以将50舍去).第一个数已经选好,接下来就是往后推进的过程,此时我想到了运用递归,一步一步往后推进,此时,如何取到最后一个数是关键,显然,第一个数与最后一个数得到,即表示所有数值和为100时,我们将该组合赋给一个字符串,并将字符串存入一个数组中,于是,所有组合的结果即可得出!
取到最后一个数,靠递归的一次推进,假设到我们从1依次推进到了14,但之前的从1一直相加到14不能等于100,于是继续推进,此时进入函数后,将剩余的数(i)循环一遍,剩余的数大小要保持在15到 (100-(1+2+3....+14))之间,在这个里面循环查找是否有满足1+2+3....+14 + i = 100.如果有的话,就将组合存入数组,并退出去,将14推移一位,变成15,如果没有的话,继续递归,向后推进,依次重复上面的步骤,直到满足为止才退出来,显然,如果1+2+3....+14小于100的话,后面一定会有个数与他们的和为100!
public partial Default : System.Web.UI.Page
{
string Result;
ArrayList arrResult = new ArrayList();
protected void Page_Load(object sender, EventArgs e)
{
//1-100 相加等于100的所有组合,不重复
for (int i = 1; i < 50; i++)
{
LastMath(i, i, i.ToString());
}
foreach (string item in arrResult)
{
Response.Write(item + "<BR/>");
}
}
/// <summary>
/// 递归计算
/// </summary>
/// <param name="maxNum">之前所有数的和</param>
/// <param name="PriNum">上一个数</param>
/// <returns>最后一个数</returns>
private int LastMath(int maxNum, int PriNum, string PriStr)
{
for (int i = PriNum + 1; i <= (100 - maxNum); i++)
{
if (i + maxNum == 100)
{
Result = PriStr + "," + i.ToString() + ";";
arrResult.Add(Result);
return i;
}
else
{
LastMath(maxNum + i, i, PriStr + "," + i.ToString());
}
}
return 0;
}
}
这是我第一次在CSDN写博客,哈哈!代码不漂亮!
下面是谈谈我对一道算法面试题的理解:
我们可以采用由前往后的方法来组合所有数字,以达到相加之和等于100的目的,可以试着推测,第一次的数字由1开始,一次往后推进,当推进到某一个数字时,他们之间的所有数之和大于100,于是我们将最后这个数丢弃,把倒数第二个数往前推进一位,可想而知,这时的所有数之和一定小于或者等于100,并且,在所剩下的数中一定有某个数
与前面所有数之和相加等于100,由于所有数不能重复,所以我们可以认为只要以前面的50个数字往后推进,后面所有组合都会被包含,所以第一个数,我们选择1-50.(因为50只有和50才能匹配,所以将50舍去).第一个数已经选好,接下来就是往后推进的过程,此时我想到了运用递归,一步一步往后推进,此时,如何取到最后一个数是关键,显然,第一个数与最后一个数得到,即表示所有数值和为100时,我们将该组合赋给一个字符串,并将字符串存入一个数组中,于是,所有组合的结果即可得出!
取到最后一个数,靠递归的一次推进,假设到我们从1依次推进到了14,但之前的从1一直相加到14不能等于100,于是继续推进,此时进入函数后,将剩余的数(i)循环一遍,剩余的数大小要保持在15到 (100-(1+2+3....+14))之间,在这个里面循环查找是否有满足1+2+3....+14 + i = 100.如果有的话,就将组合存入数组,并退出去,将14推移一位,变成15,如果没有的话,继续递归,向后推进,依次重复上面的步骤,直到满足为止才退出来,显然,如果1+2+3....+14小于100的话,后面一定会有个数与他们的和为100!
public partial Default : System.Web.UI.Page
{
string Result;
ArrayList arrResult = new ArrayList();
protected void Page_Load(object sender, EventArgs e)
{
//1-100 相加等于100的所有组合,不重复
for (int i = 1; i < 50; i++)
{
LastMath(i, i, i.ToString());
}
foreach (string item in arrResult)
{
Response.Write(item + "<BR/>");
}
}
/// <summary>
/// 递归计算
/// </summary>
/// <param name="maxNum">之前所有数的和</param>
/// <param name="PriNum">上一个数</param>
/// <returns>最后一个数</returns>
private int LastMath(int maxNum, int PriNum, string PriStr)
{
for (int i = PriNum + 1; i <= (100 - maxNum); i++)
{
if (i + maxNum == 100)
{
Result = PriStr + "," + i.ToString() + ";";
arrResult.Add(Result);
return i;
}
else
{
LastMath(maxNum + i, i, PriStr + "," + i.ToString());
}
}
return 0;
}
}
这是我第一次在CSDN写博客,哈哈!代码不漂亮!
相关文章推荐
- 一道百度算法面试题讲解
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 白话经典算法系列之十 一道有趣的GOOGLE面试题
- 每日一道算法题:微软面试题:在排序数组中,找出给定数字出现的次数
- 【白话经典算法系列之十一】一道有趣的GOOGLE面试题 --【解法2】 .
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 一道算法面试题的分析
- C#算法一道面试题浅析
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 一道别致的算法面试题
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 【算法】一道有趣的GOOGLE面试题
- 网易有道的一道算法面试题
- 白话经典算法系列之十 一道有趣的GOOGLE面试题
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 【白话经典算法系列之十】 一道有趣的GOOGLE面试题
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 一道博弈的面试题及其算法正确性证明
- 白话经典算法系列之十 一道有趣的GOOGLE面试题