zoukankan      html  css  js  c++  java
  • 剑指Offer11.旋转数组的最小数字

    题目

    把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

    示例 1:
    
    输入:[3,4,5,1,2]
    输出:1
    示例 2:
    
    输入:[2,2,2,0,1]
    输出:0
    

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题方法

    暴力法

    时间复杂度O(n)
    空间复杂度O(1)
    遍历数组,判断当前元素是否比前一个元素小,小则说明是最小元素
    如果遍历完都没有,说明数组元素都相等,或者本身是有序没有旋转的
    最终返回数组第一个元素即可。
    

    二分法

    平均时间复杂度O(logn) 当所有元素完全相同时最差O(n)
    空间复杂度O(1)
    left 左 right 右 mid 中间
    如果中间元素小于最右边元素,说明最小元素在左边
    right = mid
    如果中间元素大于最右边元素,说明最小元素在右边
    left = mid + 1 
    这里left不包含mid,因为mid属于旋转后的大元素,肯定不是最小元素
    如果中间元素等于最右边元素,无法判断最小元素所在区间
    采取抛弃最右边元素的方式 right--
    

    代码

    // 暴力法
    func minArray(numbers []int) int {
    	n := len(numbers)
    	for i:=1;i < n;i++{
    		if numbers[i] < numbers[i-1]{
    			return numbers[i]
    		}
    	}
    	return numbers[0]
    }
    
    // 二分法
    func minArray2(numbers []int) int {
    	left := 0
    	right := len(numbers)-1
    	for left < right{
    		mid := left + (right - left) / 2
    		// 如果中间元素大于最右边元素[4、5、6、1、2、3] 最小元素在右边 且不可能为中间元素
    		if numbers[mid] > numbers[right]{
    			left = mid + 1
    			// 如果中间元素小于最右元素[4、5、1、2、3] 最小元素在左边 可能包含中间元素
    		}else if numbers[mid] < numbers[right]{
    			right = mid
    		}else{
    			// 相等则抛弃右边元素
    			right--
    		}
    	}
    	return numbers[left]
    }
  • 相关阅读:
    Mapreduce实例——求平均值
    Mapreduce实例——单表join
    《短码之美》读书笔记1
    Mapreduce实例——Map端join使用addCacheFile()方法报错,找不到文件
    Mapreduce实例——Map端join
    C# 异常捕获
    Mapreduce实例——排序
    无名
    数据库设计体会
    oracle 删除表空间错误 提示:ora02429:无法删除用于强制唯一/主键的索引。
  • 原文地址:https://www.cnblogs.com/hzpeng/p/15087436.html
Copyright © 2011-2022 走看看