
Problem Statement
Imagine an integer array named nums
which is initially organized in ascending order containing unique values. However, before the array reaches your function, it may be rotated around a pivot point. The pivot point k
is an index where 1 <= k < nums.length
, dividing the array and rearranging its segments. The rotation results in the sequence beginning from nums[k]
to nums[n-1]
followed by the elements from the start of the array up to nums[k-1]
. A clear visualization is taking an array like [0,1,2,4,5,6,7]
, rotating at index 3
, and converting it to [4,5,6,7,0,1,2]
.
Given this potentially rotated array nums
and an integer target
, your task is to determine the index position of target
within nums
. If the target does not exist within the array, the function should return -1
. The challenge stipulates that your solution must have a logarithmic runtime complexity of O(log n)
in consideration of efficiency.
Examples
Example 1
Input:
nums = [4,5,6,7,0,1,2], target = 0
Output:
4
Example 2
Input:
nums = [4,5,6,7,0,1,2], target = 3
Output:
-1
Example 3
Input:
nums = [1], target = 0
Output:
-1
Constraints
1 <= nums.length <= 5000
-104 <= nums[i] <= 104
- All values of
nums
are unique. nums
is an ascending array that is possibly rotated.-104 <= target <= 104
Approach and Intuition
When facing the problem of searching in a rotated sorted array, the straightforward linear search approach, though simple, does not meet the required time complexity of O(log n)
. Instead, a modified binary search is an appropriate strategy to achieve the logarithmic runtime:
Identify Rotation Point:
- If the middle element of the array is greater than the first element, it indicates that we are in the rotated segment of the array.
- Conversely, if the middle element is less than the first element, the rotation point is in the first half.
Finding the Target:
- If the array segment being considered is not rotated (i.e., it is in perfect ascending order), standard binary search can proceed.
- If the segment is rotated, determine which half of the segment will definitely contain the target (either rotated half or the regularly ordered half) based on the target's value relative to the boundaries of the segment.
For examples:
For
nums = [4,5,6,7,0,1,2]
andtarget = 0
:- Begin with a standard binary search and adjust the search space dynamically based on whether the middle element belongs to the left or right (rotated) segment and how
target
compares to the segment's boundaries. - The target
0
falls in the latter half (rotated part of the array) after a few iterations, and its exact position can be indexed.
- Begin with a standard binary search and adjust the search space dynamically based on whether the middle element belongs to the left or right (rotated) segment and how
For
nums = [4,5,6,7,0,1,2]
andtarget = 3
:- Following similar steps, the algorithm identifies that
3
does not exist in any correctly ordered or disorderly segment, efficiently returning-1
.
- Following similar steps, the algorithm identifies that
In cases where
nums
has only one element likenums = [1]
andtarget = 0
:- The algorithm immediately identifies
0
does not match1
with minimal computation.
- The algorithm immediately identifies
This approach carefully balances the understanding of sorted array properties with efficient binary search principles, optimizing for situations where the data may not strictly adhere to initial sorting due to modifications like rotations.
Solutions
- C++
- Java
- C
- JavaScript
- Python
class Solution {
public:
int binarySearch(vector<int>& arr, int searchVal) {
int size = arr.size();
int start = 0, end = size - 1;
while (start <= end) {
int middle = start + (end - start) / 2;
if (arr[middle] == searchVal) {
return middle;
}
else if (arr[middle] >= arr[start]) {
if (searchVal >= arr[start] && searchVal < arr[middle]) {
end = middle - 1;
} else {
start = middle + 1;
}
}
else {
if (searchVal <= arr[end] && searchVal > arr[middle]) {
start = middle + 1;
} else {
end = middle - 1;
}
}
}
return -1;
}
};
In this solution to the problem of searching in a rotated sorted array using C++, you implement a modified binary search algorithm that adapts to the breakpoint where the sorting order is disrupted. The main idea revolves around dividing the array into potentially sorted subsections and then locating the target value within the appropriate subsection.
- Start by defining the
binarySearch
function that takes a reference to an integer vector and the target search value as parameters. - Initialize variables
start
andend
to define the current search range within the array, starting from the first to the last index. - Use a
while
loop to repeatedly narrow down the search range:- Calculate the middle index of the current range.
- If the value at the middle index matches the target value, return this index as the result.
- Determine which half of the array is sorted:
- If the left half from
start
tomiddle
is sorted:- Check if the target is within this range. If true, adjust
end
to narrow down the search to this half. Otherwise, search in the other half by adjustingstart
.
- Check if the target is within this range. If true, adjust
- If the left half isn't sorted, implying the right half must be:
- Check if the target falls into the sorted right half and adjust
start
orend
accordingly to focus the search.
- Check if the target falls into the sorted right half and adjust
- If the left half from
- If the loop exits without finding the target value, return -1 indicating the target isn't present in the array.
This approach maintains a logarithmic time complexity similar to a regular binary search but adds conditions to handle the peculiarities of searching within a rotated sorted structure.
class SearchAlgorithm {
public int binarySearch(int[] array, int goal) {
int length = array.length;
int start = 0, end = length - 1;
while (start <= end) {
int middle = start + (end - start) / 2;
if (array[middle] == goal) {
return middle;
}
else if (array[middle] >= array[start]) {
if (goal >= array[start] && goal < array[middle]) {
end = middle - 1;
} else {
start = middle + 1;
}
}
else {
if (goal <= array[end] && goal > array[middle]) {
start = middle + 1;
} else {
end = middle - 1;
}
}
}
return -1;
}
}
The provided Java code implements a solution for searching an element in a rotated sorted array using a modified binary search algorithm. Below summarizes the solution approach used in the code:
- The method
binarySearch
takes two parameters: an array of integersarray
and the integergoal
, which is the target to find in the array. - The binary search starts by initializing two pointers,
start
at index 0 andend
atarray.length - 1
. - Inside a while loop that continues as long as
start
is less than or equal toend
:- Calculate the middle index
middle
using the start and end indices. - Check if the element at the middle index matches the target (
goal
). If it matches, return the indexmiddle
. - Determine which half of the array to search in:
- If the element at the middle index is greater than or equal to the element at the start index, then the left half is sorted. Check if the target is within the range from
start
tomiddle
; if so, focus the search on this half by adjusting theend
pointer. - Otherwise, the right half must be sorted. Check if the target falls between the
middle
index andend
index; adjust thestart
pointer accordingly.
- If the element at the middle index is greater than or equal to the element at the start index, then the left half is sorted. Check if the target is within the range from
- Calculate the middle index
- If the target is not found in any iteration, return -1 indicating the target is not present in the array.
This approach ensures log(n) complexity by continually halving the search space and is particularly optimized for searching in an array that has been rotated from a sorted position.
int binary_search_rotated(int* array, int size, int key) {
int start = 0, end = size - 1;
while (start <= end) {
int middle = start + (end - start) / 2;
if (array[middle] == key) return middle;
else if (array[middle] >= array[start]) {
if (key >= array[start] && key < array[middle])
end = middle - 1;
else
start = middle + 1;
}
else {
if (key <= array[end] && key > array[middle])
start = middle + 1;
else
end = middle - 1;
}
}
return -1;
}
This solution efficiently handles the problem of finding an element in a rotated sorted array using a modified version of binary search implemented in C.
Function binary_search_rotated
takes three parameters:
array
- pointer to the first element of the arraysize
- number of elements in the arraykey
- the target value to search for within the array
Understand these key steps taken by the implementation:
- Initialize
start
to0
andend
tosize - 1
. - Execute a while loop that continues as long as
start
is less than or equal toend
. - Determine the middle of the current subarray with
int middle = start + (end - start) / 2
. - Check if the middle element is the key. If it is, return the index
middle
. - If the middle element is not the key, check if the left half of the array is sorted. This is done by comparing
array[middle]
witharray[start]
. - Based on the sorted half of the array, adjust the
start
andend
pointers. If the left half is sorted and the key is within the range ofstart
andmiddle
, narrow the search to the left half by settingend
tomiddle - 1
. Otherwise, adjust the search to the right half by settingstart
tomiddle + 1
. - Similar adjustments are made if the right half is sorted.
- If the key is not found in the array after exhausting the search space, return
-1
.
This function is robust and efficient, capable of handling arrays where the content has been shifted, keeping the search process within O(log n) time complexity due to its binary search nature.
var binarySearch = function (elements, value) {
let length = elements.length;
let start = 0,
end = length - 1;
while (start <= end) {
let middleIndex = start + (((end - start) / 2) | 0);
if (elements[middleIndex] == value) return middleIndex;
else if (elements[middleIndex] >= elements[start]) {
if (value >= elements[start] && value < elements[middleIndex]) end = middleIndex - 1;
else start = middleIndex + 1;
}
else {
if (value <= elements[end] && value > elements[middleIndex]) start = middleIndex + 1;
else end = middleIndex - 1;
}
}
return -1;
};
The JavaScript function binarySearch
provided above efficiently searches for a specific value within a rotated sorted array. The function implements a modified version of binary search to adapt to the nuances of a rotated array where the first part of the array is rotated to the end. Here's a breakdown of its logic and operation:
Initialize three pointers:
start
,end
to represent the range still in play for search, andmiddleIndex
to find the middle element within the current range.Run a while loop until the
start
pointer is less than or equal to theend
pointer, indicating that there are still elements to check:- Calculate
middleIndex
using the average ofstart
andend
, adjusting for integer division. - Compare the element at
middleIndex
with the target value (value
):- If a match is found, return
middleIndex
, signaling the position of the value in the array. - If no match is found, adjust the
start
andend
pointers:- If the value at
middleIndex
is greater than or equal to the value atstart
, it indicates that the left half is sorted normally.- If the target value lies between
start
andmiddleIndex
, narrow the search to the left half by adjustingend
. - Otherwise, shift focus to the right half by adjusting
start
.
- If the target value lies between
- If the previous condition isn't met, the right half must be normally sorted.
- If the target value lies between
middleIndex
andend
, narrow the search to the right half by adjustingstart
. - Otherwise, focus on the left half by adjusting
end
.
- If the target value lies between
- If the value at
- If a match is found, return
- Calculate
If the loop completes without finding the value, return
-1
to indicate the value is not present in the array.
This function ensures optimal search even in a rotated array by adjusting search boundaries intelligently based on sorted segments. It retains a time complexity of O(log n), making it efficient for large datasets.
class Solution:
def binary_search(self, array: List[int], key: int) -> int:
# Initial indices setup
low, high = 0, len(array) - 1
while low <= high:
midpoint = low + (high - low) // 2
# Check if key is present at midpoint
if array[midpoint] == key:
return midpoint
# If left side is sorted
elif array[midpoint] >= array[low]:
if key >= array[low] and key < array[midpoint]:
high = midpoint - 1
else:
low = midpoint + 1
# Right side must be sorted
else:
if key <= array[high] and key > array[midpoint]:
low = midpoint + 1
else:
high = midpoint - 1
# Key not found
return -1
The provided Python solution implements a search in a rotated sorted array using a modified binary search algorithm, enhancing typical binary search to handle the rotation.
- Implement a search within the
binary_search
method that acceptsarray
andkey
as parameters. It returns the index of the key if found, otherwise-1
. - Begin the search by initializing
low
to the start of the array andhigh
to the end. - A
while
loop continues untillow
exceedshigh
. Calculate themidpoint
inside the loop. - Check if the key is at the midpoint; return the index if true.
- Determine which segment of the array is sorted:
- If the left segment is sorted and the key lies within this segment, adjust the
high
pointer. - Otherwise, adjust the
low
pointer to search in the right segment.
- If the left segment is sorted and the key lies within this segment, adjust the
- If the key is not present in the array, the method returns
-1
after the loop concludes.
This algorithm efficiently finds the position of the given key in logarithmic time, despite the initial array being rotated. Its implementation leverages conditions to decide the continuation of the search in a specific segment based on sorted order and key location, ensuring the search is always directed towards the possible location of the key.
No comments yet.