Search in Rotated Sorted Array II - Complete Solution Guide
Search in Rotated Sorted Array II is LeetCode problem 81, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
There is an integer array nums sorted in non-decreasing order (not necessarily with distinct values). Before being passed to your function, nums is rotated at an unknown pivot index k ( 0 <= 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,4,4,5,6,6,7] might be rotated at pivot index 5 and become [4,5,6,6,7,0,1,2,4,4] . Given the array nums after the rotation and an integer target , retu
Detailed Explanation
The problem asks us to search for a target value in a rotated sorted array. The array was initially sorted in non-decreasing order but has been rotated at an unknown pivot index. The key challenge is that the array may contain duplicate values, which complicates the standard binary search approach. We need to return `true` if the target is found in the array, and `false` otherwise.
Solution Approach
The provided code implements a modified binary search algorithm to search for the target in the rotated sorted array. It maintains two pointers, `left` and `right`, initially pointing to the start and end of the array. In each iteration, it calculates the middle index `mid`. It checks if `nums[mid]` is equal to the target. If not, it determines which half of the array is sorted and checks if the target lies within that sorted half. If it does, it updates the `right` pointer; otherwise, it updates the `left` pointer. A crucial step is handling the case where `nums[left] == nums[mid]`. In this situation, we increment `left` by 1 to shrink the search window, effectively skipping the duplicate and potentially revealing the true sorted half in subsequent iterations.
Step-by-Step Algorithm
- Step 1: Initialize `left` to 0 and `right` to `nums.length - 1`.
- Step 2: While `left` is less than or equal to `right`, repeat steps 3-8.
- Step 3: Calculate the middle index `mid` as `left + (right - left) // 2`.
- Step 4: If `nums[mid]` equals the target, return `true`.
- Step 5: If `nums[left]` equals `nums[mid]`, increment `left` by 1 and continue to the next iteration. This handles the duplicate case where we can't determine which side is sorted immediately.
- Step 6: If `nums[left]` is less than `nums[mid]`, the left part of the array is sorted. Check if the target lies within this sorted portion (i.e., `nums[left] <= target < nums[mid]`). If it does, update `right` to `mid - 1`; otherwise, update `left` to `mid + 1`.
- Step 7: Otherwise (if `nums[left]` is greater than `nums[mid]`), the right part of the array is sorted. Check if the target lies within this sorted portion (i.e., `nums[mid] < target <= nums[right]`). If it does, update `left` to `mid + 1`; otherwise, update `right` to `mid - 1`.
- Step 8: If the loop completes without finding the target, return `false`.
Key Insights
- Insight 1: The presence of duplicates makes it impossible to always determine if the left or right half is sorted in O(1) time. When `nums[left] == nums[mid]`, we can't know which side is sorted, leading to a worst-case linear time complexity.
- Insight 2: We can still use a modified binary search. If `nums[left] < nums[mid]`, the left half is sorted. If `nums[left] > nums[mid]`, the right half is sorted. If `nums[left] == nums[mid]`, we increment `left` to shrink the search space.
- Insight 3: The core of the solution lies in deciding whether to search in the left or right half based on whether the target lies within the sorted portion of the array.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Array, Binary Search.
Companies
Asked at: Adobe, Amazon, Apple, Bloomberg, Meta, Microsoft, Uber, Yahoo.