Find Minimum in Rotated Sorted Array in DSA Rust - Time & Space Complexity
We want to know how fast we can find the smallest number in a rotated sorted list.
How does the time needed change as the list gets bigger?
Analyze the time complexity of the following code snippet.
fn find_min(nums: &[i32]) -> i32 {
let mut left = 0;
let mut right = nums.len() - 1;
while left < right {
let mid = left + (right - left) / 2;
if nums[mid] > nums[right] {
left = mid + 1;
} else {
right = mid;
}
}
nums[left]
}
This code finds the smallest number in a rotated sorted array using a binary search approach.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that halves the search range each time.
- How many times: The loop runs until the search range is reduced to one element, about log base 2 of n times.
Each step cuts the list roughly in half, so the number of steps grows slowly as the list grows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 4 steps |
| 100 | About 7 steps |
| 1000 | About 10 steps |
Pattern observation: Doubling the input size adds only one more step.
Time Complexity: O(log n)
This means the time needed grows slowly, adding just a few more steps even if the list gets much bigger.
[X] Wrong: "Since the list is rotated, we must check every element to find the minimum."
[OK] Correct: The binary search approach uses the sorted parts to skip many elements, so it does not need to check all.
Knowing how to use binary search in tricky ways like this shows you understand efficient searching beyond simple cases.
"What if the array contains duplicates? How would the time complexity change?"
Practice
Solution
Step 1: Understand the rotated sorted array
A rotated sorted array is a sorted array shifted some positions, so the smallest element is the rotation point.Step 2: Identify the minimum element
The minimum element is the smallest value after the rotation point, which is what we want to find.Final Answer:
To find the smallest element after the rotation point -> Option BQuick Check:
Minimum element = smallest after rotation [OK]
- Confusing minimum with maximum element
- Trying to count rotations instead of finding minimum
- Assuming array is fully sorted without rotation
Solution
Step 1: Check Rust function syntax
Rust functions start with fn, parameters have types, and return type is after ->.Step 2: Validate each option
fn find_min(nums: &[i32]) -> i32 { /* implementation */ } uses correct Rust syntax with slice &[i32] and return type i32. Others use wrong keywords or syntax.Final Answer:
fn find_min(nums: &[i32]) -> i32 { /* implementation */ } -> Option AQuick Check:
Rust fn syntax with &[i32] and -> i32 [OK]
- Using 'function' keyword instead of 'fn'
- Mixing Python or JavaScript syntax
- Incorrect return type placement
fn main() {
let nums = vec![4,5,6,7,0,1,2];
let min = find_min(&nums);
println!("{}", min);
}
fn find_min(nums: &[i32]) -> i32 {
let mut left = 0;
let mut right = nums.len() - 1;
while left < right {
let mid = left + (right - left) / 2;
if nums[mid] > nums[right] {
left = mid + 1;
} else {
right = mid;
}
}
nums[left]
}Solution
Step 1: Understand the binary search logic
The code uses binary search to find the smallest element by comparing mid and right elements.Step 2: Trace the loop with input [4,5,6,7,0,1,2]
Mid moves to find the point where array rotates; finally left points to 0, the smallest element.Final Answer:
0 -> Option AQuick Check:
Minimum in rotated array = 0 [OK]
- Returning nums[mid] instead of nums[left]
- Confusing left and right pointers
- Not handling rotation correctly
fn find_min(nums: &[i32]) -> i32 {
let mut left = 0;
let mut right = nums.len();
while left < right {
let mid = left + (right - left) / 2;
if nums[mid] > nums[right] {
left = mid + 1;
} else {
right = mid;
}
}
nums[left]
}Solution
Step 1: Check initialization of right pointer
right is set to nums.len(), which is out of array bounds (index max is len-1).Step 2: Correct right initialization
right should be nums.len() - 1 to avoid accessing nums[right] out of bounds.Final Answer:
right should be nums.len() - 1 to avoid out-of-bounds -> Option DQuick Check:
Array index max = len-1 [OK]
- Using nums.len() as index causes panic
- Starting left at 1 misses first element
- Changing mid calculation unnecessarily
fn find_min(nums: &[i32]) -> i32 {
let mut left = 0;
let mut right = nums.len() - 1;
while left < right {
let mid = left + (right - left) / 2;
if nums[mid] > nums[right] {
left = mid + 1;
} else if nums[mid] < nums[right] {
right = mid;
} else {
right -= 1; // What is the reason for this?
}
}
nums[left]
}Solution
Step 1: Understand duplicates effect
When nums[mid] equals nums[right], we cannot decide which side minimum lies, so we reduce right by one.Step 2: Reason for right -= 1
This safely shrinks the search space without missing the minimum, handling duplicates correctly.Final Answer:
To handle duplicates by shrinking right when equal to mid -> Option CQuick Check:
Duplicates need careful right pointer move [OK]
- Ignoring duplicates causes wrong minimum
- Moving left instead of right when equal
- Assuming no duplicates in rotated array
Ready to prove it?
Pass the test and this pattern moves unknown
