剑指offer:旋转数组的最小数字

题目

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

解题思路

这是一道二分查找的变形题,这里的旋转数组是两个有序的递增子数组拼接起来的,且前面一个子数组里的任意一个数都大于后面子数组中的数。而要找的最小值就是前后两个子数组的分界点。

用三个指针begin、end、middle分别指向数组的首尾和中间元素

1)若middle元素大于或者等于begin元素说明中间元素位于前半部分数组中,最小元素在后半部分的数组中,则将begin设为middle继续在后半部分中寻找

2)若middle元素小于或者等于end元素说明中间元素位于后半部分数组中,最小部分在前半部分或者中间元素就是最小元素,则将end设为middle继续在前半部分中寻找

这样不断缩小范围,直到最后begin和end会成为相邻的元素,此时end所指元素就是最小值

特殊情况:

1)0个元素旋转到后半部分,那么此时旋转数组就是一个非递减数组,最小值就是第一个元素,也就是为什么初始middle设为0的原因

2)当begin、end、middle三个元素都相等时,无法判断中间元素在前半部分数组还是后半部分数组,只能遍历数组寻找最小值

例如1,1,1,0,1和1,0,1,1,1都可以看成是0,1,1,1,1的翻转数组

代码

 1     public int minNumberInRotateArray(int [] array) {
 2         if(array.length==0)
 3             return 0;
 4         int begin = 0,end = array.length-1,middle = 0;
 5         while(array[begin]>=array[end]){
 6             if((end-begin)==1){
 7                 middle = end;
 8                 break;
 9             }
10             middle = (begin+end)/2;
11             if(array[begin]==array[middle]&&array[middle]==array[end]){
12                 return minInOrder(array,begin,end);
13             }
14             if(array[middle]>=array[begin]){
15                 begin = middle;
16             }else if(array[middle]<=array[end]){
17                 end = middle;
18             }
19
20         }
21         return array[middle];
22     }
23
24     private int minInOrder(int[] array,int begin,int end){
25         int min = array[begin];
26         for(int i = begin+1;i<end;i++){
27             if(min>array[i]){
28                 min = array[i];
29             }
30         }
31         return min;
32     }

原文地址:https://www.cnblogs.com/huanglf714/p/11069485.html

时间: 2024-11-05 22:57:58

剑指offer:旋转数组的最小数字的相关文章

剑指offer—旋转数组的最小数字

题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组(3,4,5,1,2)位{1,2,3,4,5}的一个旋转,该数组的最小值为1. 基本思想: 二分查找,p1指向a[0],p2指向a[len-1].如果a[mid]>a[p1],则最小值在后半段,p1=mid:如果a[mid]<a[p2],则最小值在前半段,p2=mid. 特殊情况: 注意:在这两个数组中,第一个数字.最后一个数字和中间数字都是1,我们无法

剑指offer旋转数组的最小数字python

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 思路 旋转后的数组先递增,然后突然断层,让后又递增,所以,只要找到数组突然变小的那个数字即可. 代码 # -*- coding:utf-8 -*- class Solution: def minNumberInRot

剑指offer——旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 建议读者自己思考以后再看答案 废话不多说,看代码: public class MinNumberInRotateArray { public static int minNumberInRotateArray(int [] arr) { int low = 0; int high = a

[剑指offer] 旋转数组的最小数字

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减序列的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入描述 一个非递减序列的一个旋转数组 输出描述 输出旋转数组的最小元素 题目分析 原数组最小的值必然是第一个,旋转后数组是两个非递减数组的拼接,只要找到第二个非递减数组的第一个元素就是最小值. 遍历旋转数组,只要有array[i+1]小于array[i],那么array[i+1]

剑指:旋转数组的最小数字

旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个升序的数组的一个旋转,输出旋转数组的最小元素. 例如数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的一个旋转,该数组的最小值为 1. 数组可能包含重复项. 注意:数组内所含元素非负,若数组大小为 0,请返回 -1. 样例 输入:nums=[2,2,2,0,1] 输出:0 解法 解法一 直接遍历数组找最小值,时间复杂度 O(n),不推荐. class Solution { /**

剑指Offer_11_旋转数组的最小数字

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出一个旋转数组的最小元素. 例如: {3,4,5,1,2} 为 {1,2,3,4,5} 对应的一个旋转数组,该数组的最小元素为 1 .  分析: 方法一: 因为数组的原数组是一个递增数组,所以从头遍历数组,出现 a[i] 小于 a[i-1] 则说明找到了最小元素,为 a[i]. 1 int FindMinNumber(int arr[],int length){ // arr为旋转数组

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

看起来不需要用二分法查找 --------------------------------------------------------- 时间限制:3秒 空间限制:32768K 热度指数:509802 本题知识点: 查找 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0

剑指Offer-6.旋转数组的最小数字(C++/Java)

题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 分析: 这道题和LeetCode上153,154是一样的.只不过153的数组元素是不重复的,154则允许数组有重复元素. 这里直接要求输入的是非递减排序的数组,所以和154题是一样的. LeetCode 153. Fi

剑指offer8 旋转数组的最小数字

一种错误写法: class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { int length = rotateArray.size(); if(length <= 0) return 0; if(rotateArray[0] == rotateArray[length-1] && rotateArray[0] == rotateArray[(length-1)/2]){

6、剑指offer--旋转数组的最小数字

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 解题思路:本题中因为旋转后的两个子数组分别是有序的,因此不需要完全遍历一遍得到结果,采用二分查找的方法解决:注意特殊情况左=中间=右,只能采用遍历进行处理 1 #include <iostream> 2 #i