golang剑指offer-008.旋转数组的最小数字

题目大意

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减序列的一个旋转,输出旋转数组的最小元素。
例如:数组{3,4,5,1,2)就是{1,2,3,4,5}的一个旋转。

输入示例

{3,4,5,1,2}

输出示例

该数组最小值为1.

解题思路

既然是查找最小元素,那么可以考虑使用二分查找法,用两个指针分别指向数组的第一个元素和最后一个元素。旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后面子数组的元素。我们还可以注意到最小的元素刚好是这两个子数组的分界线。

用两个指针分别指向数组的第一个元素和最后一个元素。
接着对数组中的元素:

  • 1.如果该中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针指向的元素。此时数组中最小的元素应该位于该中间元素的后面。这样可以把第一指针指向该中间元素,这样可以缩小寻找的范围。
  • 2.同样,如果中间元素位于后面的递增子数组,那么它应该小于或者等于第二个指针指向的元素。此时该数组中最小的元素应该位于该中间元素的前面。我们可以把第二个指针指向该中间元素,这样同样可以缩小寻找的范围。
  • 3.一直循环1和2直到结束。
func MinNumberInArray(array []int) int {
	low, high := 0, len(array)-1
	// 因为是旋转,所以第一个元素一定大于最后一个元素
	// 否则,第一个元素就是那个最小的元素
	if array[low] < array[high] {
		return array[low]
	}
	mid = (log + high) / 2
	for array[low] >= array[high] {
		if high - low == 1 {
			mid = high
			break
		}
		mid = (low + htgh) / 2
		// 考虑一种特殊情况
		// 当 array[low] == array[mid] == array[high] 时
		// 只能老老实实按照正常顺序查找
		if array[low] == array[mid] && array[mid] == array[high] {
			return MinInOrder(array, low, high)
		}
		if array[mid] >= array[low] {
			low = mid
		} else {
			high = mid
		}
	}
	return array[mid]
}

// 顺序查找
func MinInOrder(array []int, low, high int) int {
	min := array[low]
	for i := low; i <= high; i++ {
		if array[i] < min {
			min = array[i]
		}
	}
	return min
}

// 顺序查找中另外一种方法
// 把数组重新拍一下,然后找出第一个元素(但这肯定不是面试官想要的结果)
func MinInOrderII(array []int) int {
	sort.Slice(array, func(i ,j int) bool {
		return array[i] < array[j] 
	})
	return array[0]
}
发布了16 篇原创文章 · 获赞 0 · 访问量 1300

猜你喜欢

转载自blog.csdn.net/weixin_41036574/article/details/104009388