Recursion on Arrays and Strings in DSA Javascript - Time & Space Complexity
When using recursion on arrays or strings, it is important to know how the number of steps grows as the input gets bigger.
We want to find out how many times the function calls itself and how that affects the total work done.
Analyze the time complexity of the following code snippet.
function sumArray(arr, index = 0) {
if (index === arr.length) return 0;
return arr[index] + sumArray(arr, index + 1);
}
This function adds all numbers in an array by calling itself for each element.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive call to sumArray for each element in the array.
- How many times: Once per element, so n times for an array of size n.
Each element causes one recursive call, so the total steps grow directly with the number of elements.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 recursive calls |
| 100 | About 100 recursive calls |
| 1000 | About 1000 recursive calls |
Pattern observation: The work grows in a straight line as input size increases.
Time Complexity: O(n)
This means the time to finish grows directly with the number of elements in the array.
[X] Wrong: "Recursion always makes code slower by a lot, so it must be worse than loops."
[OK] Correct: Here, recursion visits each element once, just like a loop would, so the time is similar.
Understanding how recursion works on arrays and strings helps you explain your code clearly and shows you can think about how fast it runs.
What if we changed the function to call itself twice for each element? How would the time complexity change?
Practice
Solution
Step 1: Understand recursion on arrays
Recursive functions handle one element and then call themselves on the smaller part (rest of the array).Step 2: Identify the typical recursive pattern
This pattern reduces the problem size by one element each call until the array is empty.Final Answer:
It processes one element and calls itself on the rest of the array. -> Option BQuick Check:
Recursion = process one + recurse rest [OK]
- Thinking recursion processes all elements at once
- Confusing recursion with loops
- Ignoring the base case
Solution
Step 1: Check base case and recursive call
function recurse(arr) { if(arr.length === 0) return; recurse(arr.slice(1)); } correctly checks if array is empty and calls itself with the rest of the array using slice(1).Step 2: Identify incorrect syntax in other options
The version using while(arr.length > 0) recurse(arr); causes infinite recursion because it passes the same array; the version using for loop calls recurse on individual elements; the version using arr.pop() passes a single element, not an array.Final Answer:
function recurse(arr) { if(arr.length === 0) return; recurse(arr.slice(1)); } -> Option AQuick Check:
Base case + recurse smaller array = correct syntax [OK]
- Missing base case causing infinite recursion
- Passing wrong argument type in recursive call
- Using loops inside recursion incorrectly
function sumArray(arr) {
if (arr.length === 0) return 0;
return arr[0] + sumArray(arr.slice(1));
}
console.log(sumArray([1, 2, 3, 4]));Solution
Step 1: Understand the recursive sum logic
The function adds the first element to the sum of the rest recursively until array is empty.Step 2: Calculate sum step-by-step
1 + sumArray([2,3,4]) = 1 + (2 + sumArray([3,4])) = 1 + 2 + 3 + 4 = 10Final Answer:
10 -> Option DQuick Check:
Sum of [1,2,3,4] = 10 [OK]
- Concatenating numbers as strings
- Forgetting base case returns 0
- Using arr.pop() which mutates array
function reverseStr(str) {
if (str.length === 1) return str;
return reverseStr(str.slice(1)) + str[0];
}
console.log(reverseStr('abc'));Solution
Step 1: Analyze base case condition
Base case checks if string length is 1, but for empty string it should return empty string to avoid errors.Step 2: Understand recursion on empty string
If input is empty, function should return empty string to stop recursion safely.Final Answer:
Base case should check for empty string, not length 1. -> Option AQuick Check:
Base case empty string needed for safe recursion [OK]
- Using wrong base case length
- Confusing slice indexes
- Assuming function works without base case
[1, [2, [3, 4], 5], 6], which recursive approach correctly flattens it into [1, 2, 3, 4, 5, 6]?Solution
Step 1: Identify recursive flattening logic
To flatten nested arrays, check each element: if array, recurse; else add to result.Step 2: Understand why other options fail
Loops alone can't flatten nested arrays fully; one-level flattening misses deeper nesting; returning original array does nothing.Final Answer:
Check if element is array, recursively flatten it, else add element to result. -> Option CQuick Check:
Recursive flatten = check array + recurse + add element [OK]
- Flattening only one level
- Not checking if element is array
- Ignoring nested deeper arrays
Ready to prove it?
Pass the test and this pattern moves unknown
