↓Skip to main content
  1. LeetCode/

LeetCode 33: Search in Rotated Sorted Array

·2 mins· ·
LeetCode Medium Array Binary-Search
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-10-21

  • Submissions: Wrong Answer → Accepted → Wrong Answer → Accepted → Wrong Answer → Accepted → Wrong Answer ×4 → Accepted → Wrong Answer ×2 → Accepted → Wrong Answer → Accepted → Runtime Error → Accepted ×4

Approach
#

Splitting at mid, at least one of [l, mid] and [mid, r] is sorted (Binary Search):

  • nums[l] <= nums[mid]: the left half is sorted. Go left if the target lies in [nums[l], nums[mid]), otherwise right.
  • Otherwise the right half is sorted. Go right if the target lies in (nums[mid], nums[r]], otherwise left.

Only the sorted half can tell whether the target is inside.

My Attempts
#

My first accepted version in 2022 was actually a linear scan (O(n)). The dozen WAs while practicing binary search all chose the wrong direction:

  • One decided with nums[mid] >= target first and then checked a range, but the half it checked was not necessarily sorted: [8, 9, 10, 3], target = 10 should be 2; it returned -1.
  • One moved left whenever nums[r] >= target, the reverse direction: [1, 5], target = 5 returned -1.

Solution
#

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        l, r = 0, len(nums) - 1
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] == target:
                return mid
            if nums[l] <= nums[mid]:                     # 左半有序
                if nums[l] <= target < nums[mid]:
                    r = mid - 1
                else:
                    l = mid + 1
            else:                                        # 右半有序
                if nums[mid] < target <= nums[r]:
                    l = mid + 1
                else:
                    r = mid - 1
        return -1

Complexity
#

Time O(log n), space O(1).

Mistakes to Avoid
#

  • First decide which half is sorted, then whether the target is in it; comparing nums[mid] with the target alone cannot choose a direction.
  • nums[l] <= nums[mid] needs the equality (when l == mid).

Interview Explanation
#

After rotation one side of mid is always sorted; I find which, check whether the target falls in its range, and search there or the other side. Time O(log n).

Related

LeetCode 34: Find First and Last Position of Element in Sorted Array
·2 mins
LeetCode Medium Array Binary-Search
LeetCode 34 note: two lower bounds: the first position >= target, and the first position >= target + 1 minus one
LeetCode 31: Next Permutation
·2 mins
LeetCode Medium Array Two-Pointers
LeetCode 31 note: from the right find the first dip i, swap it with the smallest larger value to its right, then reverse everything after i, with comparisons that include equality
LeetCode 36: Valid Sudoku
·2 mins
LeetCode Medium Array Hash-Table Matrix
LeetCode 36 note: each digit may appear once per row, column and 3 × 3 box; put (digit, row), (digit, column) and (digit, box) keys into one set
LeetCode 39: Combination Sum
·2 mins
LeetCode Medium Array Backtracking
LeetCode 39 note: numbers may be reused, so the next level starts at i (not i + 1), which also avoids duplicates differing only in order
LeetCode 40: Combination Sum II
·2 mins
LeetCode Medium Array Backtracking
LeetCode 40 note: each number is used once and duplicates exist, so sort, start the next level at i + 1, and skip equal values within a level
LeetCode 46: Permutations
·2 mins
LeetCode Medium Array Backtracking
LeetCode 46 note: each level picks one unused number, marked in a used array, and records when the path is full