Lever's Castle

33. 搜索旋转排序数组

May 05, 2020

https://leetcode-cn.com/problems/search-in-rotated-sorted-array/

解:

func search(nums []int, target int) int {
    if len(nums) == 0 {
        return -1
    }
    var minIndex int
    min := nums[0]
    for i, num := range nums {
        if i == 0 {
            continue
        }
        if min > num {
            min = num
            minIndex = i
        }
    }
    var maxIndex, max int
    if minIndex == 0 {
        maxIndex = len(nums) - 1
    } else {
        maxIndex = minIndex - 1
    }
    max = nums[maxIndex]
    if target < min {
        return -1
    } else if target > max {
        return -1
    }

    if min == target {
        return minIndex
    } else if max == target {
        return maxIndex
    }
    if minIndex == maxIndex {
        return -1
    }

    offset := minIndex - 0
    middleIndex := (len(nums) + 1) / 2 - 1 + offset
    if middleIndex >= len(nums) {
        middleIndex = middleIndex - len(nums)
    }
    if middleIndex >= 0 && middleIndex < len(nums) {
        middle := nums[middleIndex]
        if middle == target {
            return middleIndex
        } else if middle > target {
            if middleIndex >= minIndex {
                result := search(nums[minIndex:middleIndex], target)
                if result == -1 {
                    return -1
                }
                return result + minIndex
            }
            right := search(nums[minIndex:], target)
            if right != -1 {
                return right + minIndex
            }
            left := search(nums[:middleIndex], target)
            return left
        } else {
            if middleIndex <= maxIndex {
                result := search(nums[middleIndex:maxIndex], target)
                if result == -1 {
                    return -1
                }
                return result + middleIndex
            } else {
                right := search(nums[middleIndex:], target)
                if right != -1 {
                    return right + middleIndex
                }
                left := search(nums[:maxIndex], target)
                return left
            }
        }
    }

    return -1
}

解题思路

先看到一些题目中的关键信息:有序,O(logn)。从这两个信息我们就能想到二分查找,通过不断的缩小查找范围来。这里比较复杂的地方在于这个数组可能是旋转过的,不过还好,总是有规律可循。

  • 只要找到最小的元素,最大的元素一定是其前一个
  • 二分点依然按照有序数组的方式来选择,即数组的中间位置的元素。但是选择完之后,要进行偏移处理。这里需要分别考虑中位数落在右边和落在左边的情况。
  • 缩小查找范围,递归查找

Lever

痕迹
没有过去,就没法认定现在的自己