Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Both of these approaches are correct. It is indeed legal to have multiple recursive calls from a function, and the meaning is what you'd think - just do one call, then the next, then the next, etc.</p> <p>Interestingly, I don't think that the recursive version does make exponentially many calls. It makes at most two recursive calls, but each are on a problem whose size is (approximately) half as large as the original call. Essentially, the recurrence looks like this:</p> <pre><code>T(1) = 1 T(2) = 1 T(n) &lt;= T(n / 2) + T(n / 2 + 1) + 1 </code></pre> <p>I use "less than or equal to here" to say that in the best case you might just make one call, but in the worst case you make at most two.</p> <p>I want to prove that this function T(n) &lt;= max{cn + d, a} for some constants c, d, and a. This would prove that T(n) = O(n) and thus makes at most linearly many calls. As our base case, we have that</p> <pre><code>T(1) = 1 T(2) = 1 </code></pre> <p>so let's set a = 1. For the inductive step, we consider three cases. First, let's consider when floor(n / 2) &lt;= 2 and floor(n / 2 + 1) &lt;= 2:</p> <pre><code>T(n) &lt;= T(n / 2) + T(n / 2 + 1) + 1 &lt;= 1 + 1 + 1 &lt;= 3 </code></pre> <p>If we assume that cn + d >= 3, when n = 3 or n = 4, then this works out correctly. In particular, this means that 3c + d >= 3 and 4c + d >= 3.</p> <p>In the next case, let's see what happens if floor(n / 2) &lt;= 2 and floor(n / 2 + 1) >= 2. Then we have that</p> <pre><code>T(n) &lt;= T(n / 2) + T(n / 2 + 1) + 1 &lt;= 1 + max{c(n / 2 + 1) + d, 1} + 1 &lt;= 2 + max{c(n / 2 + 1) + d, 1} &lt;= 3 + c(n / 2 + 1) + d </code></pre> <p>So if we have that 3 + c(n / 2 + 1) + d &lt;= cn + d, this claim still holds. Note that we're only in this case if n = 5, and so this means that we must have that</p> <pre><code>3 + c(n / 2 + 1) + d &lt;= cn + d 3 + c(n / 2 + 1) &lt;= cn 3 + c(5 / 2 + 1) &lt;= 5c 3 + 5c/2 + c &lt;= 5c 3 + 7c/2 &lt;= 5c 4 &lt;= 3c / 2 8 / 3 &lt;= c </code></pre> <p>So we must have that c >= 8 / 3.</p> <p>And finally, the case where neither n / 2 nor n / 2 + 1 are less than three:</p> <pre><code>T(n) &lt;= T(n / 2) + T(n / 2 + 1) + 1 &lt;= c(n / 2) + d + c(n / 2 + 1) + d + 1 &lt;= cn / 2 + cn / 2 + c + 2d + 1 = cn + c + 2d + 1 </code></pre> <p>This is less than cn + d if</p> <pre><code> cn + c + 2d + 1 &lt;= cn + d c + 2d + 1 &lt;= d c + d + 1 &lt;= 0 </code></pre> <p>This works if d = -c - 1.</p> <p>From earlier, we know that 3c + d >= 3, which works if 2c - 1 >= 3, or 2c >= 4, so c >= 2. We also have that 4c + d >= 3, which also works if c >= 2. Letting c = 8 / 3, we get that d = -11 / 3, so</p> <pre><code>T(n) &lt;= max{8n/3 - 11/3, 1} </code></pre> <p>So T(n) = O(n) and the recursion makes only linearly many calls.</p> <hr> <p>The short version of this is that both the recursive and iterative versions take linear time. Don't fear recursion's exponential-time blowup without being sure it's exponential. :-) Though admittedtly, in this case, I really like the iterative version more. It's clearer, more intuitive, and more immediately O(n).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload