Skip to main content

Search in Rotated Sorted Array

LeetCode 33 | Difficulty: Medium​

Medium

Problem Description​

There is an integer array nums sorted in ascending order (with distinct values).

Prior to being passed to your function, nums is possibly left rotated at an unknown index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be left rotated by 3 indices and become [4,5,6,7,0,1,2].

Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

You must write an algorithm with O(log n) runtime complexity.

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`

- `-10^4 <= nums[i] <= 10^4`

- All values of `nums` are **unique**.

- `nums` is an ascending array that is possibly rotated.

- `-10^4 <= target <= 10^4`

Topics: Array, Binary Search


Approach​

Binary search reduces the search space by half at each step. The key insight is identifying the monotonic property β€” what condition lets you decide to go left or right?

When to use

Sorted array, or searching for a value in a monotonic function/space.


Solutions​

Solution 1: C# (Best: 142 ms)​

MetricValue
Runtime142 ms
MemoryN/A
Date2017-11-04
Solution
public class Solution {
public int Search(int[] nums, int target) {

if(nums.Length == 0) return -1;
int lo = 0, high = nums.Length - 1;
while (lo <= high)
{
int mid = (lo + high)/2;
int num = (nums[mid] < nums[0]) == (target < nums[0])
? nums[mid]
: target < nums[0] ? Int32.MinValue : Int32.MaxValue;
if (num < target)
{
lo = mid+1;
}
else if (num > target)
{
high = mid-1;
}
else return mid;
}
return -1;
}
}
πŸ“œ 3 more C# submission(s)

Submission (2022-02-23) β€” 158 ms, 37.9 MB​

public class Solution {
public int Search(int[] nums, int target) {

int l = 0, r = nums.Length-1;
while(l<=r)
{
int mid = l + (r-l)/2;
if(target == nums[mid])
{
return mid;
}

if(nums[l] <= nums[mid])
{
if(target >= nums[l] && target < nums[mid])
{
r = mid-1;
}
else
{
l = mid+1;
}
}
else if(nums[mid] < nums[r])
{
if(target > nums[mid] && target <= nums[r])
{
l = mid+1;
}
else
{
r = mid-1;
}
}
}
// Write your code here.
return -1;
}
}

Submission (2017-11-04) β€” 192 ms, N/A​

public class Solution {
public int Search(int[] nums, int target) {
int lo = 0, high = nums.Length - 1;
while (lo <= high)
{
int mid = (lo + high)/2;
int num = (nums[mid] < nums[0]) == (target < nums[0])
? nums[mid]
: target < nums[0] ? Int32.MinValue : Int32.MaxValue;
if (num < target)
{
lo = mid+1;
}
else if (num > target)
{
high = mid-1;
}
else return mid;
}
return -1;
}
}

Submission (2017-11-04) β€” 192 ms, N/A​

public class Solution {
public int Search(int[] nums, int target) {
if(nums.Length<1) return -1;
int lo = 0, high = nums.Length - 1;
while (lo < high)
{
int mid = 1+(lo + high)/2;
if(nums[mid] == target) return mid;

if (nums[lo] < nums[mid])
{
if(target >= nums[lo] && target < nums[mid])
high = mid -1;
else
lo = mid+1;
}
else
{
if (target > nums[mid] && target <= nums[high])
{
lo = mid+1;
}
else
{
high = mid-1;
}
}
}

return (lo>=0 && lo<nums.Length && nums[lo]==target) ? lo : -1;
}
}

Complexity Analysis​

ApproachTimeSpace
Binary Search$O(log n)$$O(1)$

Interview Tips​

Key Points
  • Discuss the brute force approach first, then optimize. Explain your thought process.
  • Precisely define what the left and right boundaries represent, and the loop invariant.