题目要求
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思想
首先我们可以对于一个递增数组来说,它的最小值出现在数组索引为0的位置,那么将递增数组进行旋转后,该最小值应出现在数列最大值的后面一个的位置。或者直接可以把该题理解为求数字的最小值。
Go语言实现
第一种方法:遍历查找
首先我们可以通过遍历的方式求最小值,当我们找到第一个比旋转后数组0索引位置的数字小的数字就可以跳出循环,并返回该数字:
func minArray(numbers []int) int {
min := numbers[0]
for _,v := range numbers{
if(min>v){
min = v
break
}
}
return min
}
这种情况下,时间复杂度最大是O(n),由于我们所使用的是数据定义在for循环之外,所以空间复杂度为O(1)
第二种方法:二分法查找
关于查找数组中的最小值,二分法无疑是最简单的查找方式。
func minArray(numbers []int) int {
left := 0
right := len(numbers) - 1
for left < right {
mid := left + (right - left) / 2
if numbers[mid] < numbers[right] {
right = mid
} else if numbers[mid] > numbers[right] {
left = mid + 1
} else {
right--
}
}
return numbers[left]
}
对于二分法查找的时间复杂度计算,对于n个元素的二分查找:
第n次二分剩下n/(2^m),在最坏情况下是在排除到只剩下最后一个值之后得到结果,即
n/(2^m)=1
所以由上式可得 : 2^m=n,进而可求出时间复杂度为: log2(n)
空间复杂度:O(1)。
第三种方法:排序
当然Go语言的sort包里面也为我们提供了排序工具,我们可以直接对数组进行排序并输出数组的第一个元素就可以得到最小值。
func minArray(numbers []int) int {
sort.Ints(numbers)
return numbers[0]
}
使用java实现
二分法
class Solution {
public int minArray(int[] numbers) {
int l = 0;
int r = numbers.length - 1;
while (l < r) {
int m = l + (r - l) / 2;
if (numbers[m] < numbers[r]) {
high = m;
} else if (numbers[m] > numbers[r]) {
l = m + 1;
} else {
r -= 1;
}
}
return numbers[l];
}
}
暴力法
class Solution {
public int minArray(int[] numbers) {
int min = numbers[0];
for(int num:numbers){
if(min>num){
min = num;
break;
}
}
return min;
}
}
时间复杂度空间复杂度同上。