LeetCode - Algorithms
  • Introduction
  • 1. Two Sum
  • 2. Add Two Numbers
  • 3. Longest Substring Without Repeating Characters
  • 4. Median of Two Sorted Arrays
  • 5. Longest Palindromic Substring
  • 6. ZigZag Conversion
  • 7. Reverse Integer
  • 8. String to Integer (atoi)
  • 9. Palindrome Number
  • 10. Regular Expression Matching
  • 11. Container with Most Water
  • 12. Integer to Roman
  • 13. Roman to Integer
  • 14. Longest Common Prefix
  • 15. 3Sum
  • 16. 3Sum Closest
  • 17. Letter Combinations of a Phone Number
  • 18. 4Sum
  • 19. Remove Nth Node From End of List
  • 20. Valid Parentheses
  • 21. Merge Two Sorted Lists
  • 22. Generate Parentheses
  • 23. Merge k Sorted Lists
  • 24. Swap Nodes in Pairs
  • 25. Reverse Nodes in k-Group
  • 26. Remove Duplicates from Sorted Array
  • 27. Remove Element
  • 28. Implement strStr()
  • 29. Divide Two Integers
  • 30. Substring with Concatenation of All Words
  • 31. Next Permutation
  • 32. Longest Valid Parentheses
  • 33. Search in Rotated Sorted Array
  • 34. Search for a Range
  • 35. Search Insert Position
  • 36. Valid Sudoku
  • 37. Sudoku Solver
  • 38. Count and Say
  • 39. Combination Sum
Powered by GitBook
On this page
  • Problem
  • Analysis
  • Code

33. Search in Rotated Sorted Array

Problem

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

Related Topics:

Array Binary Search

Analysis

方法一:先找出最小值所在的下标,确定目标在哪一边,然后进行二分查找。

方法二:当 target < nums[mid] 时,存在三种情况。

  • 两则都在分割线(最小值与最大值之间)的左边:为升序,target 在 nums[mid] 左边,所以 nums[mid] 右边的元素舍弃,即 end = mid - 1。

  • 两则都在分割线的右边:为升序,同上,end = mid - 1。

  • 由于分割线左边元素大于右边,所以 target 在右边,nums[mid] 在左边:舍弃 nums[mid] 左边元素,即 start = mid + 1。

同理,target > nums[mid] 时,也有三种情况,处理方法类似。

Code

找最小值:

class Solution {

    fun search(nums: IntArray, target: Int): Int {

        if (nums.isEmpty()) return -1

        val minIndex = findMin(nums)
        var start: Int
        var end: Int
        var mid: Int

        when {
            target > nums[nums.lastIndex] -> {
                start = 0
                end = minIndex - 1
            }
            else -> {
                start = minIndex
                end = nums.lastIndex
            }
        }

        while (start <= end) {
            mid = (start + end) / 2
            when {
                target == nums[mid] -> return mid
                target < nums[mid] -> end = mid - 1
                target > nums[mid] -> start = mid + 1
            }
        }

        return -1
    }

    private fun findMin(nums: IntArray): Int {

        var start = 0
        var end = nums.lastIndex
        var mid: Int

        while (start < end) {
            mid = (start + end) / 2
            when {
                nums[mid] > nums[end] -> start = mid + 1
                else -> end = mid
            }
        }

        return start
    }
}

所有情况判断:

class Solution {

    fun search(nums: IntArray, target: Int): Int {

        var start = 0
        var end = nums.lastIndex
        var mid: Int

        while (start <= end) {

            mid = (start + end) / 2

            when {
                target > nums[end] && nums[mid] <= nums[end] -> end = mid - 1
                target <= nums[end] && nums[mid] > nums[end] -> start = mid + 1
                else -> {
                    when {
                        target < nums[mid] -> end = mid - 1
                        target > nums[mid] -> start = mid + 1
                        else -> return mid
                    }
                }
            }
        }

        return -1
    }
}
Previous32. Longest Valid ParenthesesNext34. Search for a Range

Last updated 6 years ago