Given a sorted array arr[] of n elements, write a function to search a given element x in arr[].
Input: A sorted array, arrA[] and an key
Output : Return index if element is found, else -1.
OR
Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1.
You must write an algorithm with O(log n) runtime complexity.
A straightforward method is to perform a linear search. The time complexity of this approach is ( O(n) ). An alternative method is to use Binary Search.
Binary Search is based on the principle of divide and conquer, aiming to find an item in an ordered list recursively.
To search a sorted array, continually divide the search interval in half. Start with the whole array. If the search key is less than the middle item, reduce the interval to the lower half. Otherwise, reduce it to the upper half. Repeat until the value is found or the interval is empty.
classSolution {
publicintsearch(int[] nums, int target) {
return binarySearch(nums, target, 0, nums.length- 1);
}
privateintbinarySearch(int[] nums, int target, int left, int right) {
// Base condition: if left exceeds right, the search space is exhaustedif (left > right) {
return-1; // Target not found }
int mid = left + (right - left) / 2; // Calculate the midpoint safely to avoid overflow// Check if the midpoint element matches the targetif (nums[mid]== target) {
return mid; // Target found } elseif (nums[mid]> target) {
return binarySearch(nums, target, left, mid - 1); // Search in the left subarray } else {
return binarySearch(nums, target, mid + 1, right); // Search in the right subarray }
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defsearch(self, nums: List[int], target: int) -> int:
return self.binary_search(nums, target, 0, len(nums) -1)
defbinary_search(self, nums: List[int], target: int, left: int, right: int) -> int:
# Base condition: if left exceeds right, the search space is exhaustedif left > right:
return-1# Target not found mid = left + (right - left) //2# Calculate the midpoint safely to avoid overflow# Check if the midpoint element matches the targetif nums[mid] == target:
return mid # Target foundelif nums[mid] > target:
return self.binary_search(nums, target, left, mid -1) # Search in the left subarrayelse:
return self.binary_search(nums, target, mid +1, right) # Search in the right subarray
intBinarySearch(int A[], int key){
int m, l = 0, r = A.length- 1;
while( r - l > 1 ) {
m = l + (r-l)/2;
if( A[m]<= key )
l = m;
else r = m;
}
if( A[l]== key )
return l;
elsereturn-1;
}
classSolution {
publicintsearch(int[] nums, int target) {
int left = 0, right = nums.length- 1;
while (left <= right) {
int mid = (left + right) / 2; // Calculate the middle indexif (nums[mid]== target) {
return mid; // Element found } elseif (nums[mid]> target) {
right = mid - 1; // Search in the left half } else {
left = mid + 1; // Search in the right half }
}
return-1; // Element not found in the array }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
classSolution:
defsearch(self, nums: List[int], target: int) -> int:
left, right =0, len(nums) -1while left <= right:
mid = (left + right) //2# Calculate the middle indexif nums[mid] == target:
return mid # Element foundelif nums[mid] > target:
right = mid -1# Search in the left halfelse:
left = mid +1# Search in the right halfreturn-1# Element not found in the array
In Binary Search, with each iteration, we discard half the elements and continue searching with the remaining half until the target element is found or the search space is empty. In each iteration, the search space is halved. For instance, if the search space has ( n ) elements:
Iteration 1: ( n/2 = n/2^1 )
Iteration 2: ( (n/2)/2 = n/4 = n/2^2 )
Iteration 3: ( (n/4)/2 = n/8 = n/2^3 )
This process terminates when we have one element left in the array and assume the iteration number as k
Iteration k: n/2^k = 1 => k =log2(n)
Time Complexity = log2(n) where n is the number of elements in the search space.