golang之leetcode33 旋转数组求值实现

题目:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

求解思路:
由题可知,有序,不重复数组,查询数组中等于某值的index, 复杂度为O(log n) ,联想到了二分查找法。

众所周知,二分查找必须是在有序数据里面进行。但是由于数组发生了旋转,所以说数据并不是全部有序,不过我们还是可以仿照之前二分法的处理逻辑,比如每次取一个mid, 那么数据会被分为[0,mid].
[mid+1,end]两个数组,总有一个是有序的,那么我们就可以去判断有序的数组,进而在决定mid应该取在哪个区间。

比如上面的数组,我们需要查找等于2的index? 我们第一次去的mid为7,即index为3的位置,可以看到【0,mid】之间有序的,我们判断之后,发现并不在这个区间内,所以我们需要丢弃这个区间,去[mid+1,end]里面去找,即数组中index为【4,6】的数组里面查找,之后再去查找得到6即是2在数组中的index。

代码实现

func LeetCode33(arr []int, value int) int {
	start := 0
	end := len(arr) - 1

	mid := start + (end-start)/2

	if len(arr) == 1 {
		if arr[0] != value {
			return -1
		}
	}

	for start <= end {
		if arr[mid] == value {
			return mid
		}
		if arr[0] <= arr[mid] {
			if arr[0] <= value && arr[mid] > value {
				end = mid - 1
			} else {
				start = mid + 1
			}
		} else {
			if arr[mid] < value && arr[end] >= value {
				start = mid + 1
			} else {
				end = mid - 1
			}
		}
		mid = start + (end-start)/2

	}
	return -1
}

测试:

package binarysearch

import (
	"fmt"
	"testing"
)

func TestFindFirstByBinarySearch(t *testing.T) {
	fmt.Println("旋转数组")
	arr4:=[]int{4,5,6,7,0,1,2}
	res4 :=LeetCode33(arr4,2) // 2,6  ; 5,1
	fmt.Println(res4)

	fmt.Println("旋转数组1")
	arr5:=[]int{6,7,0,1,2,4,5}
	res5 :=LeetCode33(arr5,6) //6,0  ; 4,5
	fmt.Println(res5)
}

output

2
旋转数组
6
旋转数组1
0

你可能感兴趣的:(数据结构和算法相关)