Problem Statement
Given a sorted array of integers nums with 0-based indexing, find the index of a specified target integer. If the target is found in the array, return its index. If the target is not found, return -1.
Examples
Example 1:
Input: nums = [-1, 0, 1, 5, 7, 9], target = 7
Output: 4
Explanation: The target element 7 is present at index 4 in the array.
Example 2:
Input: nums = [0, 1, 2, 3, 4, 4, 5], target = 4
Output: 4
Explanation: There are two occurrences of the element 4,
However the first occurrence is at index 4.
Different Approach
Intuition:
Since the array is sorted, we can efficiently search for the element using Binary Search. Binary search works by repeatedly dividing the search space into halves. We compare the middle element of the current search space with x
:
- If the middle element equals
x
, we return the index. - If
x
is smaller than the middle element, we discard the right half and continue searching in the left half. - If
x
is larger than the middle element, we discard the left half and continue searching in the right half.
This process continues until either the element is found or the search space is exhausted.
1️⃣ Iterative Approach
Algorithm (Iterative Approach):
- Set
left = 0
andright = n - 1
. - While
left <= right
:- Compute the middle index:
mid = left + (right - left) / 2
. - If
arr[mid] == x
, returnmid
(element found). - If
arr[mid] > x
, setright = mid - 1
(search in the left half). - If
arr[mid] < x
, setleft = mid + 1
(search in the right half).
- Compute the middle index:
- If
x
is not found, return-1
.
Dry Run:
Target = 9
+-----+-----+-----+-----+-----+-----+
arr[] = | 1 | 3 | 5 | 7 | 9 | 11 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
left = 0
right = 5
First Iteration:
Target = 9
left = 0
right = 5
mid = left + (right - left) / 2
= 0 + (5 - 0) / 2 = 5 / 2 = 2
+-----+-----+-----+-----+-----+-----+
arr[] = | 1 | 3 | 5 | 7 | 9 | 11 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^ ^
| | |
left mid right
since arr[mid] < target
2 < 9
set left = mid + 1
Second Iteration:
Target = 9
left = 3
right = 5
mid = left + (right - left) / 2
= 3 + (5 - 3) / 2 = 3 + 2 / 2 = 3 + 1 = 4
+-----+-----+-----+-----+-----+-----+
arr[] = | 1 | 3 | 5 | 7 | 9 | 11 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^ ^
| | |
left mid right
since arr[mid] == target
9 == 9
return mid index.
Code:
#include <iostream>
#include <vector>
using namespace std;
int binarySearchIterative(const vector<int>& arr, int x) {
int left = 0, right = arr.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == x)
return mid; // Element found
else if (arr[mid] < x)
left = mid + 1; // Search the right half
else
right = mid - 1; // Search the left half
}
return -1; // Element not found
}
int main() {
vector<int> arr = {1, 3, 5, 7, 9, 11, 13};
int x = 9;
int index = binarySearchIterative(arr, x);
if (index != -1)
cout << "Element found at index " << index << endl;
else
cout << "Element not found" << endl;
return 0;
}
Complexity Analysis:
Time Complexity:
- Both the iterative and recursive approaches perform a binary search in O(log n) time, as the search space is halved in each iteration/recursion.
- Best Case: O(1) when the element is found at the middle.
- Worst Case:
O(log n)
when the element is not present or is at the extremes of the array.
- Both the iterative and recursive approaches perform a binary search in O(log n) time, as the search space is halved in each iteration/recursion.
- Space Complexity:
- Iterative Approach:
O(1)
as only a few extra variables are used.
- Iterative Approach:
2️⃣ Recursive Approach
Code:
#include <iostream>
using namespace std;
int binarySearchRecursive(int arr[], int left, int right, int target) {
if (left <= right) {
int mid = left + (right - left) / 2;
// Base case: target found
if (arr[mid] == target)
return mid;
// If target is smaller, search in the left half
else if (arr[mid] > target)
return binarySearchRecursive(arr, left, mid - 1, target);
// If target is larger, search in the right half
else
return binarySearchRecursive(arr, mid + 1, right, target);
}
// Target not found
return -1;
}
int main() {
int arr[] = {2, 4, 6, 8, 10, 12, 14};
int n = sizeof(arr) / sizeof(arr[0]);
int target = 8;
int result = binarySearchRecursive(arr, 0, n - 1, target);
if (result != -1)
cout << "Element found at index " << result << endl;
else
cout << "Element not found" << endl;
return 0;
}
Complexity Analysis:
- Time Complexity:
O(log n)
, wheren
is the number of elements.- Because the array is divided in half at each step.
- Space Complexity:
O(log n)
, wheren
is the number of elements.- Because the recursion stack used for each function call.