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.
Input: nums = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: The target integer 9 exists in nums and its index is 4
Input: nums = [-1,0,3,5,9,12], target = 2
Output: -1
Explanation: The target integer 2 does not exist in nums so return -1
Input: nums = [-1,0,3,5,9,12], target = -1
Binary search is an efficient algorithm to find a target value within a sorted array. It works on the idea of repeatedly dividing the search space(the space in which the search of the target is taking place) in half until the target is found or it is concluded that the target is not present in the array.
The target must be found in the array itself. This means that the space in which the target must be searched for is the array. Now, to mark the search space, two pointers will come in hand -
Low:
A pointer pointing to the smallest index possible of the search space.High:
A pointer pointing to the greatest index possible of the search space.low = 0, high = n-1
(where n is the size of the array)
If the target is not present in the array, the search space will eventually reduce to zero with every search indicating the absence of target in the given array. In such cases, -1 can be returned.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find the given target in a sorted array
int search(vector<int>& nums, int target) {
int n = nums.size(); // Size of array
// Pointers to define the search space
int low = 0, high = n-1;
// Until the search space is not empty
while (low <= high) {
// Find the middle element
int mid = (low + high) / 2;
// If it matches the target
if (nums[mid] == target)
return mid;
// If the target is greater than middle element
else if (target > nums[mid])
low = mid + 1;
// Otherwise
else
high = mid - 1;
}
// If the target is not found
return -1;
}
};
int main() {
vector<int> a = {-1, 0, 3, 5, 9, 12};
int target = 9;
// Creating an instance of Solution class
Solution sol;
// Function call to find the given target in a sorted array
int ind = sol.search(a, target);
if(ind == -1)
cout << "The target is not present." << endl;
else
cout << "The target is at index: " << ind << endl;
return 0;
}
import java.util.*;
class Solution {
// Function to find the given target in a sorted array
public int search(int[] nums, int target) {
int n = nums.length; // Size of array
// Pointers to define the search space
int low = 0, high = n - 1;
// Until the search space is not empty
while (low <= high) {
// Find the middle element
int mid = (low + high) / 2;
// If it matches the target
if (nums[mid] == target)
return mid;
// If the target is greater than middle element
else if (target > nums[mid])
low = mid + 1;
// Otherwise
else
high = mid - 1;
}
// If the target is not found
return -1;
}
public static void main(String[] args) {
int[] a = {-1, 0, 3, 5, 9, 12};
int target = 9;
// Creating an instance of Solution class
Solution sol = new Solution();
// Function call to find the given target in a sorted array
int ind = sol.search(a, target);
if (ind == -1)
System.out.println("The target is not present.");
else
System.out.println("The target is at index: " + ind);
}
}
class Solution:
# Function to find the given target in a sorted array
def search(self, nums, target):
n = len(nums) # Size of array
# Pointers to define the search space
low, high = 0, n - 1
# Until the search space is not empty
while low <= high:
# Find the middle element
mid = (low + high) // 2
# If it matches the target
if nums[mid] == target:
return mid
# If the target is greater than middle element
elif target > nums[mid]:
low = mid + 1
# Otherwise
else:
high = mid - 1
# If the target is not found
return -1
# Creating an instance of Solution class
sol = Solution()
# Test the function
a = [-1, 0, 3, 5, 9, 12]
target = 9
# Function call to find the given target in a sorted array
ind = sol.search(a, target)
if ind == -1:
print("The target is not present.")
else:
print("The target is at index:", ind)
class Solution {
// Function to find the given target in a sorted array
search(nums, target) {
let n = nums.length; // Size of array
// Pointers to define the search space
let low = 0, high = n - 1;
// Until the search space is not empty
while (low <= high) {
// Find the middle element
let mid = Math.floor((low + high) / 2);
// If it matches the target
if (nums[mid] === target)
return mid;
// If the target is greater than middle element
else if (target > nums[mid])
low = mid + 1;
// Otherwise
else
high = mid - 1;
}
// If the target is not found
return -1;
}
}
// Creating an instance of Solution class
let sol = new Solution();
// Test the function
let a = [-1, 0, 3, 5, 9, 12];
let target = 9;
// Function call to find the given target in a sorted array
let ind = sol.search(a, target);
if (ind === -1)
console.log("The target is not present.");
else
console.log("The target is at index: " + ind);
Time Complexity: O(log(N)) (where N is the size of the given array)
In each step, the search space is divided into two halves. In the worst case, this process will continue until the search space can no longer be divided and the number of divisions required to reduce the array size to one is log(N), making the overall time complexity O(log(N)).
Space Complexity: O(1)
Using only a couple of variables.
Binary search is an efficient algorithm to find a target value within a sorted array. It works on the idea of repeatedly dividing the search space(the space in which the search of the target is taking place) in half until the target is found or it is concluded that the target is not present in the array.
The target must be found in the array itself. This means that the space in which the target must be searched for is the array. Now, to mark the search space, two pointers will come in hand -
Low:
A pointer pointing to the smallest index possible of the search space.High:
A pointer pointing to the greatest index possible of the search space.low = 0, high = n-1
(where n is the size of the array)
If the target is not present in the array, the search space will eventually reduce to zero (when high and low) with every search indicating the absence of target in the given array. In such cases, -1 can be returned.
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
// Helper function to find the target in the given range
int func(vector<int> &nums, int low, int high, int target) {
// base case
if(low > high) return -1;
int ind; // to store the index of target
int mid = low + (high - low)/2;
// If target is found, return the index
if(nums[mid] == target) ind = mid;
// Else if nums[mid] > target, search is left space
else if(nums[mid] > target) ind = func(nums, low, mid-1, target);
// Else search in right space
else ind = func(nums, mid+1, high, target);
return ind; // Return the index
}
public:
// Function to find the given target in a sorted array
int search(vector<int> &nums, int target){
int n = nums.size();
// Find the target in the whole array
return func(nums, 0, n-1, target);
}
};
int main() {
vector<int> a = {-1, 0, 3, 5, 9, 12};
int target = 9;
// Creating an instance of Solution class
Solution sol;
// Function call to find the given target in a sorted array
int ind = sol.search(a, target);
if(ind == -1)
cout << "The target is not present." << endl;
else
cout << "The target is at index: " << ind << endl;
return 0;
}
class Solution {
// Helper function to find the target in the given range
private int func(int[] nums, int low, int high, int target) {
// base case
if(low > high) return -1;
int ind; // to store the index of target
int mid = low + (high - low)/2;
// If target is found, return the index
if(nums[mid] == target) ind = mid;
// Else if nums[mid] > target, search is left space
else if(nums[mid] > target) ind = func(nums, low, mid-1, target);
// Else search in right space
else ind = func(nums, mid+1, high, target);
return ind; // Return the index
}
// Function to find the given target in a sorted array
public int search(int[] nums, int target){
int n = nums.length;
// Find the target in the whole array
return func(nums, 0, n-1, target);
}
}
class Main {
public static void main(String[] args) {
int[] a = {-1, 0, 3, 5, 9, 12};
int target = 9;
// Creating an instance of Solution class
Solution sol = new Solution();
// Function call to find the given target in a sorted array
int ind = sol.search(a, target);
if(ind == -1)
System.out.println("The target is not present.");
else
System.out.println("The target is at index: " + ind);
}
}
class Solution:
# Helper function to find the target in the given range
def func(self, nums, low, high, target):
# base case
if low > high:
return -1
# to store the index of target
mid = low + (high - low)//2
# If target is found, return the index
if nums[mid] == target:
ind = mid
# Else if nums[mid] > target, search is left space
elif nums[mid] > target:
ind = self.func(nums, low, mid-1, target)
# Else search in right space
else:
ind = self.func(nums, mid+1, high, target)
return ind # Return the index
# Function to find the given target in a sorted array
def search(self, nums, target):
n = len(nums)
# Find the target in the whole array
return self.func(nums, 0, n-1, target)
def main():
a = [-1, 0, 3, 5, 9, 12]
target = 9
# Creating an instance of Solution class
sol = Solution()
# Function call to find the given target in a sorted array
ind = sol.search(a, target)
if ind == -1:
print("The target is not present.")
else:
print("The target is at index:", ind)
if __name__ == "__main__":
main()
class Solution {
// Helper function to find the target in the given range
func(nums, low, high, target) {
// base case
if(low > high) return -1;
let ind; // to store the index of target
let mid = low + Math.floor((high - low)/2);
// If target is found, return the index
if(nums[mid] === target) ind = mid;
// Else if nums[mid] > target, search is left space
else if(nums[mid] > target) ind = this.func(nums, low, mid-1, target);
// Else search in right space
else ind = this.func(nums, mid+1, high, target);
return ind; // Return the index
}
// Function to find the given target in a sorted array
search(nums, target) {
let n = nums.length;
// Find the target in the whole array
return this.func(nums, 0, n-1, target);
}
}
function main() {
let a = [-1, 0, 3, 5, 9, 12];
let target = 9;
// Creating an instance of Solution class
let sol = new Solution();
// Function call to find the given target in a sorted array
let ind = sol.search(a, target);
if(ind === -1)
console.log("The target is not present.");
else
console.log("The target is at index:", ind);
}
main();
Time Complexity: O(logN), where N is the size of the array
In each step, the search space is divided into two halves. In the worst case, this process will continue until the search space can no longer be divided and the number of divisions required to reduce the array size to one is log(N), making the overall time complexity O(logN).
Space Complexity: O(logN), due to the recursion stack space.
Q: Why not use linear search?
A: While linear search works, it requires O(n) time. Binary search reduces the complexity to O(logn), which is much faster for large arrays.
Q: What if the array is infinite?
A: For an infinite sorted array, start with a bounded range and double the range size until the target is within the bounds. Then apply binary search within that range.
Q: How would you modify binary search to find the first or last occurrence of the target?
A: To find the first occurrence, adjust your logic to continue searching the left half even after finding a match. Similarly, for the last occurrence, search the right half after finding a match. This ensures you locate the boundary of duplicate elements.
Q: What if the array is rotated?
A: For a rotated sorted array, modify the binary search to check which half of the array is sorted at each step. Use this information to decide whether to search in the left or right half.