剑指offer-JZ6

题目描述

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

输入

复制
[3,4,5,1,2]

返回值

复制
1

思路:

1.二分:

  根据题意我们可以知道,给出的数组可以被视为由一个(未旋转)或两个(发生选择)非递减数组组成。

  定义ps为数组开始下标,pe为数组结束下标,mid=(ps+pe)/2

  那么:如果array[mid] >= array[pe],则最小值一定在mid右侧

     如果array[mid] <= array[ps],则最小值一定为mid或在mid左侧

  这样我们就可以在迭代求解时,每次都将问题规模缩小一半,进而缩短时间。

  我们可以递归的实现:

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int len = rotateArray.size();
        if(len == 0)
            return 0;
        int minn = Solve(rotateArray,0,len-1);
        return minn;
    }
      
    int Solve(vector<int> rotateArray, int ps, int pe)
    {
        if(ps >= pe)
            return rotateArray[ps];
        int mid = (ps+pe)/2;
        int right_n = rotateArray[ps], left_n = rotateArray[ps];
        if(rotateArray[mid] >= rotateArray[pe])
        {
            right_n =  Solve(rotateArray,mid+1,pe);
        }
        else if(rotateArray[mid] <= rotateArray[ps])
        {
            left_n =  Solve(rotateArray,ps,mid);
        }
        return min(right_n,left_n);
    }
};
View Code

  也可以非递归的实现:

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int len = rotateArray.size();
        if(len == 0)
            return 0;
        int minn = Solve(rotateArray,0,len-1);
        return minn;
    }
      
    int Solve(vector<int> rotateArray, int ps, int pe)
    {
        int ans = rotateArray[ps];
        while(ps < pe)
        {
            int mid = (ps+pe)/2;
            if(rotateArray[mid] >= rotateArray[pe])
            {
                ps = mid+1;
            }
            else
            {
                pe = mid;
            }
        }
        ans = min(ans,rotateArray[ps]);
        return ans;
    }
};
View Code

2.暴力:

  暴力最容易想到的思路,但是如果裸暴力你可能剑指不到offer

  假设最小值为minn,对于array[k]==minn,肯定存在k使得array[k] < array[k-1](特殊情况除外:数组未发生旋转或数组内所有元素大小相同)

  我们同时从数组的两端寻找这样的k值即可,实现时有些小技巧来帮助我们节省时间

static const auto _=[](){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return nullptr;
}();
class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        for(int i=0,j=rotateArray.size()-1;i<j;i++,j--){
            if(rotateArray[i]>rotateArray[i+1]) return rotateArray[i+1];
            if(rotateArray[j]<rotateArray[j-1]) return rotateArray[j];
        }
        return rotateArray.empty()?0:rotateArray[0];
    }
};
View Code

 

 

posted @ 2021-01-03 20:05  声声醉如兰  阅读(79)  评论(0编辑  收藏  举报