What if you could solve big problems by solving tiny pieces again and again automatically?
Why Recursion on Arrays and Strings in DSA Rust?
Imagine you have a long list of numbers or a long word, and you want to find something inside it or change it step by step. Doing this by hand means checking each item one by one, which can be very slow and tiring.
Manually going through each item in a list or each letter in a word can be confusing and easy to mess up. You might forget where you left off or make mistakes counting. It also takes a lot of time if the list or word is very long.
Recursion lets you solve the problem by breaking it into smaller, similar problems. You tell the computer to solve a small part, then call itself to solve the next part, until it finishes. This way, the computer handles the steps automatically and correctly.
fn sum_array(arr: &[i32]) -> i32 {
let mut total = 0;
for i in 0..arr.len() {
total += arr[i];
}
total
}fn sum_array(arr: &[i32]) -> i32 {
if arr.is_empty() {
0
} else {
arr[0] + sum_array(&arr[1..])
}
}Recursion on arrays and strings makes it easy to solve complex problems by breaking them into simple, repeatable steps.
Think of reading a book page by page. Instead of remembering the whole book, you read one page, then ask yourself to read the next page, and so on, until you finish the book.
Manual checking of arrays or strings is slow and error-prone.
Recursion breaks problems into smaller, manageable parts.
It helps write clear and simple solutions for complex tasks.
Practice
Solution
Step 1: Understand recursion on arrays
Recursion on arrays means the function calls itself with a smaller portion of the array each time.Step 2: Identify the base case
The recursion stops when the array is empty or has one element (base case).Final Answer:
Calling the same function with a smaller part of the array until a base case is reached -> Option BQuick Check:
Recursion = smaller input calls [OK]
- Confusing recursion with loops
- Not defining a base case
- Trying to process the whole array at once
Solution
Step 1: Understand Rust slice parameter
A recursive function processing an array usually takes a slice reference like &[i32] to avoid ownership issues.Step 2: Check return type
Returning i32 is common if the function calculates a value like sum or count.Final Answer:
fn recurse(arr: &[i32]) -> i32 -> Option DQuick Check:
Slice input with reference = fn recurse(arr: &[i32]) -> i32 [OK]
- Using Vec<i32> causes ownership moves
- Returning a reference to local data
- Using mutable slice when not needed
arr = &[1, 2, 3]?
fn sum(arr: &[i32]) -> i32 {
if arr.is_empty() {
0
} else {
arr[0] + sum(&arr[1..])
}
}
println!("{}", sum(arr));Solution
Step 1: Trace recursive calls
sum(&[1,2,3]) = 1 + sum(&[2,3]) sum(&[2,3]) = 2 + sum(&[3]) sum(&[3]) = 3 + sum(&[]) sum(&[]) = 0 (base case)Step 2: Calculate total sum
sum = 1 + 2 + 3 + 0 = 6Final Answer:
6 -> Option CQuick Check:
1+2+3 = 6 [OK]
- Forgetting base case returns 0
- Adding wrong slice range
- Confusing output with length
fn count_occurrences(arr: &[i32], target: i32) -> i32 {
if arr.len() == 0 {
0
} else if arr[0] == target {
1 + count_occurrences(&arr[1..], target)
} else {
count_occurrences(arr, target)
}
}Solution
Step 1: Analyze recursive calls
In the else branch, the function calls itself with the same array slice, causing infinite recursion.Step 2: Identify fix
The else branch should call with &arr[1..] to move forward and avoid infinite loop.Final Answer:
Infinite recursion because the else branch calls with the same array slice -> Option AQuick Check:
Same slice call causes infinite recursion [OK]
- Not reducing slice in else branch
- Confusing base case condition
- Returning wrong type
s: &str, which recursive Rust function correctly reverses the string?Solution
Step 1: Understand string slicing and recursion
To reverse, recursively reverse substring from index 1 onward, then append first character.Step 2: Check base case and concatenation order
Base case is empty string returning empty String. Concatenate reversed tail + first char.Step 3: Compare options
fn reverse(s: &str) -> String { if s.len() == 0 { String::new() } else { format!("{}{}", reverse(&s[1..]), &s[0..1]) } } matches correct base case and concatenation order.Final Answer:
fn reverse(s: &str) -> String { if s.len() == 0 { String::new() } else { format!("{}{}", reverse(&s[1..]), &s[0..1]) } } -> Option AQuick Check:
Reverse tail + first char = correct recursion [OK]
- Appending first char before recursive call
- Wrong base case condition
- Using incorrect string slices
Ready to prove it?
Pass the test and this pattern moves unknown
