leetcode 33 搜索旋轉排序數組

題目描述

假設按照升序排序的數組在預先未知的某個點上進行了旋轉。git

( 例如,數組 [0,1,2,4,5,6,7] 可能變爲 [4,5,6,7,0,1,2] )github

搜索一個給定的目標值,若是數組中存在這個目標值,則返回它的索引,不然返回 -1golang

你能夠假設數組中不存在重複的元素。面試

你的算法時間複雜度必須是 O(log n) 級別。算法

示例1:數組

輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4
複製代碼

示例2:bash

輸入: nums = [4,5,6,7,0,1,2], target = 3
輸出: -1
複製代碼

代碼實現

//1. 先二分遍歷找到分隔點index,特徵是 < 前一個元素, >後一個元素;
//2. 把數組分紅二個部分,[0,index-1], [index,length-1];
//3. 分別使用二分查找,找到給定的值。
//時間複雜度爲log(n). 不肯定有什麼更好的辦法

func search(nums []int, target int) int {
	if len(nums) == 0 {
		return -1
	}

	n := len(nums) - 1
	divisionIndex := findDivision(nums)
	if divisionIndex == 0 || divisionIndex == -1 {
		//非旋轉排序數組
		return findTarget(nums, 0, n, target)
	}

	res := findTarget(nums, 0, divisionIndex-1, target)
	if res != -1 {
		return res
	}
	return findTarget(nums, divisionIndex, n, target)
}

//找到分割點
func findDivision(nums []int) int {
	low, high := 0, len(nums)-1
	for low < high {
		mid := low + (high-low)>>1

		if nums[high] < nums[mid] {
			low = mid + 1
		} else {
			high = mid
		}
	}
	return low
}

func findTarget(nums []int, low, high, target int) int {
	for low <= high {
		mid := low + (high-low)>>1
		if nums[mid] > target {
			high = mid - 1
		} else if nums[mid] < target {
			low = mid + 1
		} else {
			return mid
		}
	}
	return -1
}
複製代碼

思路

  • 先二分遍歷找到分隔點index,特徵是 < 前一個元素, >後一個元素;
  • 把數組分紅二個部分,[0,index-1], [index,length-1];
  • 分別使用二分查找,找到給定的值。

GitHub

參考資料

leetcode 33. 搜索旋轉排序數組數據結構

本文爲原創文章,轉載註明出處,歡迎掃碼關注公衆號 樓蘭 或者網站lovecoding.club,第一時間看後續精彩文章,以爲好的話,順手分享到朋友圈吧,感謝支持。網站

image
相關文章
相關標籤/搜索