这是一个问题:你想要以楼梯形状形成总共n个硬币,其中每个第k行必须有正好k个硬币。给予n,找到完整楼梯的总数可以形成的行。 n是一个非负整数,适合32位有符号整数的范围。
这是我下面的递归解决方案。
public class Solution {
public int Solver(int n, int m) {
if(n - m < m || n == 0) {
return m;
}
m++;
return Solver(n - m, m);
}
public int ArrangeCoins(int n) {
return Solver(n, 0);
}
}
这是我得到的错误:
Runtime Error Message:
Unhandled Exception:
StackOverflowException
Stack overflow in unmanaged: IP: 0x5c441d, fault addr: 0x7fff33c3b0b8
Stack overflow in unmanaged: IP: 0x7f7a0fef6bbc, fault addr: 0x7fff33c3af68
Unhandled Exception:
StackOverflowException
Stack overflow in unmanaged: IP: 0x5681fc, fault addr: 0x7fff33c3bff8
Stack overflow in unmanaged: IP: 0x5c441d, fault addr: 0x7fff33c3a478
Stack overflow in unmanaged: IP: 0x7f7a0fef6bbc, fault addr: 0x7fff33c39fe8
Stack overflow in unmanaged: IP: 0x4b1567, fault addr: 0x7fff33c3bcc0
Stack overflow in unmanaged: IP: 0x5c441d, fault addr: 0x7fff33c39698
[ERROR] FATAL UNHANDLED EXCEPTION: Nested exception detected.
Original Exception: at (wrapper managed-to-native) System.IO.MonoIO.Close (intptr,System.IO.MonoIOError&) [0x00026] in <2e7c1c96edae44d496118948ca617c11>:0
at System.IO.FileStream.Dispose (bool) [0x00037] in <2e7c1c96edae44d496118948ca617c11>:0
at System.IO.Stream.Close () [0x00002] in <2e7c1c96edae44d496118948ca617c11>:0
at System.IO.StreamWriter.Dispose (bool) [0x00045] in <2e7c1c96edae44d496118948ca617c11>:0
at System.IO.TextWriter.Dispose () [0x00002] in <2e7c1c96edae44d496118948ca617c11>:0
at __Driver__.Main (string[]) [0x00066] in __Driver__.cs:41
Nested exception:at string.FillStringChecked (string,int,string) [0x00006] in <2e7c1c96edae44d496118948ca617c11>:0
at string.Concat (string,string,string) [0x00049] in <2e7c1c96edae44d496118948ca617c11>:0
at System.Exception.ToString (bool,bool) [0x0002e] in <2e7c1c96edae44d496118948ca617c11>:0
at System.Exception.ToString () [0x00003] in <2e7c1c96edae44d496118948ca617c11>:0
Last executed input: 1957747793
我知道这个解决方案有效,因为我可以在任何其他IDE上运行它,它适用于此错误的特定输入。究竟我做错了什么?
以下证明它适用于该输入:http://rextester.com/CNJ29548
我可以使用数学来更快地解决这个问题,但我想提高我的递归技能,这似乎是一个完美的问题。帮助
答案 0 :(得分:1)
&#34;我知道这个解决方案有效&#34;。我担心你可能已经使用了programmer's proof,因为&#34; 6&#34;是&#34; 2&#34 ;;和&#34; 10&#34;和11&#34;返回&#34; 3&#34;。试试这个......
public int Solver(int coinsRemaining, int coinsOnNextRow)
{
if (coinsRemaining >= coinsOnNextRow)
{
return Solver(coinsRemaining - coinsOnNextRow, coinsOnNextRow + 1);
}
return coinsOnNextRow - 1;
}
public int ArrangeCoins(int n)
{
return Solver(n, 1);
}
仍然会获得该值的堆栈溢出,但至少它正在通往正确的答案:)
我认为问题在于使用堆栈,因为您正在使用递归。这里不需要递归...只需使用while循环(这适用于您想要的输入,给出62573作为答案,是吗?):
public int ArrangeCoins(int coinsRemaining)
{
int coinsOnNextRow = 1;
while (coinsRemaining >= coinsOnNextRow)
{
coinsRemaining -= coinsOnNextRow;
coinsOnNextRow++;
}
return coinsOnNextRow - 1;
}