当使用Java(或任何其他程序语言)编程时,我经常选择递归地解决某些内容与迭代地解决它。递归选项通常比迭代解决方案更优雅,所以我通常会选择递归解决方案。有一个例外:
担心堆栈溢出如果最大堆栈深度与输入的大小成线性比例(或更差),我倾向于避免递归解决方案。然而我意识到,在许多其他语言中(甚至是针对JVM的那些语言,例如Scala和Clojure),许多算法(例如基本列表算法)通常以递归方式表示,其中最大堆栈深度与列表的长度成比例。 sup>(1)那么,我担心线性堆栈深度算法中的堆栈溢出是否合理?
TL; DR:什么“堆栈深度复杂度”被认为是合理的?对数复杂度,例如递归二进制搜索, O(log N)肯定没问题,但是 O(N), O(N log N)< / em>, O(N 2 )?您通常会在哪里画线?(2)
(1)我意识到这些语言有时支持像@tailrec这样的东西,但这个问题涉及Java,C#等。
(2)注意我不是关注CPU开销等。只是堆栈深度。
答案 0 :(得分:2)
堆栈深度复杂性是需要考虑的一件事,但另一件事是输入大小本身。
如果问题排除了其域的大量输入(对于开发过程中的扩展时间段),那么我们可以进行递归解决(当然,递归解决方案不得超过容量具有最大可能输入的堆栈。)
如果未定义输入大小,则可以接受O(1)堆栈深度或O(log N)堆栈深度,恕我直言。如果输入大小的实际上限在天文数值上超过堆栈容量,则O(log N)可能是不可接受的。但是,我认为这种情况很少见。
答案 1 :(得分:1)
如果不问自己想要支持的尺寸输入,就无法回答这个问题。
如果您正在处理一副扑克牌,那么筹码上的线性空间复杂度绝对不错,如果您正在接收大量文本文件,则可能完全无望。您需要确定应用程序的最大输入大小,或者更确切地说,您不会想到它失败的最大输入。
我们一直这样做。例如,每次在Java中声明一个数组时,您都知道该数组中不能包含2个以上 31 元素。那有关系吗?这是否意味着该计划被打破?可能不是;但有时确实如此,如果你希望能够处理大量的投入。
所以我不认为你对这个过于规范。如果有人问(用相当笼统的话)时间复杂度是多少,你会怎么说?你可能会说一些一般原则:通常线性是好的,通常指数是坏的......但真正的答案是,这取决于你正在做什么。