旋转数组最小值

将一个非递减序列的某一处切一刀,再把前半段序列放到后半段序列的后面,这样组成的新序列叫做“旋转数组”。要求获取一个旋转数组的最小值。给定数组arr及它的大小n,请返回最小值。

测试样例:
[4,1,2,3,3],5
返回:1

思路

如果旋转的长度为0,即arr[0]<arr[n-1],数组仍然是一个非递减序列,直接返回第一个元素即可.

否则将数组看成两个排序的子数组, 最小的元素就是两个数组的分界点.用二分查找的思想去查找分界点.

如果arr[lo]>arr[mid],说明arr[mid]肯定落在了第二个子数组上,此时hi=mid.
如果arr[mid]>arr[hi],说明arr[mid]肯定落在了第一个子数组上,此时lo=mid.
lo和hi逐步向分界点逼近,直到arr[lo]是第一个子数组的最后一个元素,arr[hi]元素是第二个子数组的第一个元素,即分界点.此时返回arr[hi].

如果上述两个条件都不满足,说明arr[lo]<=arr[mid],并且arr[hi]>=arr[mid],又有arr[lo]>=arr[hi],得出arr[lo]=arr[mid]=arr[hi].此时没有办法缩小范围.只能通过遍历的方式去查找最小值.

代码

 public int getMin(int[] arr, int n) {
        int lo=0,hi=n-1;
        int mid=0;
        if(arr[lo]<arr[hi]){
            return arr[lo];
        } 
        while(lo!=hi-1){                 
            mid=lo+(hi-lo)/2;            
            if(arr[lo]>arr[mid]){    
                hi=mid;
            }
            else if(arr[mid]>arr[hi]){ 
                lo=mid;
            }
            else{              
                while(lo<=hi&&arr[lo]==arr[hi]){
                    lo++;
                }
                return arr[lo];
            }
        }
        return arr[hi];
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 最近在读< >时,了解到了很多常用的排序算法,故写一篇读书笔记记录下这些排序算法的思路和实现. 冒泡排序 冒泡排序...
    SylvanasSun阅读 842评论 0 0
  • 旋转数组的最小数字 题目 给定一个递增的旋转数组A,返回旋转数组中的最小值。旋转数组:给定一个已排序的数组,假设为...
    蓝雪冬荷阅读 527评论 0 0
  • 一. 写在前面 要学习算法,“排序”是一个回避不了的重要话题,在分析完并查集算法和常用数据结构之后,今天我们终于可...
    Leesper阅读 2,672评论 0 40
  • 四. 走向世界之巅——快速排序 你可能会以为归并排序是最强的算法了,其实不然。回想一下,归并的时间效率虽然高,但空...
    Leesper阅读 2,041评论 9 7
  • 背小包,是极简生活的开始! 像我一般都会背双肩包,感觉有太多的东西要装进去:书,手机,耳机,伞,唇膏等等,感觉不背...
    好听的暖阳阅读 385评论 1 2

友情链接更多精彩内容