返回旋转数组中最小值

题目描述

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

 

/*

 * 思路:
 *      1、遍历整个数组,返回最小值,时间复杂度O(n)
 *      2、因为数组是旋转数组,而且旋转数组是一个非递减的数组,所以旋转点处为整个数组最小元素,时间复杂度优于方法1
 *      3、二分法,优于前两种方法,时间复杂度为O(logN)
 *
 * 输出:
 * 测试数据为: 3 4 5 6 2 3 3
 * 共 7 个数据
 * ---------------
 * 方法1共循环 7 次
 * 方法1的结果是:2
 * ---------------
 * 方法2共循环 4 次
 * 方法2的结果是: 2
 * ---------------
 * 方法3共循环 1 次
 * 方法3的结果是: 2
 */

 


#include <iostream>
#include <vector>

using namespace std;
 class Solution{
 public:
     //方法1:遍历数组,找到最小的元素
     int minNumberInRotateArray(vector<int> rotateArray) {
         int timeCaluation = 0;
         int result = 2147483647;
         if(rotateArray.size() == 0)
             return 0;
         for (int i = 0; i < rotateArray.size() ; ++i) {
                timeCaluation ++;
                if(result > rotateArray[i])
                    result = rotateArray[i];
         }
         cout << "---------------" << endl;
         cout << "方法1共循环 " << timeCaluation << " 次" << endl;
         cout << "方法1的结果是:" << result << endl;
         return result;
     }

     /* 方法2:从数组第一个开始,每相邻两个进行对比,旋转之前是非递减,故当遇到array[i]>array[i+1]时,
      *         array[i+1]便是数组中最小的元素
      *         */
        int method2MinNumberInRotateArray(vector<int> array){

            int timeCaculation = 0;
            if(array.size() == 0)
                return 0;
         for (int i = 0; i < array.size()-1 ; ++i) {
                timeCaculation ++ ;
             if(array[i] > array[i+1]){

                 cout << "---------------"
                << endl << "方法2共循环 " << timeCaculation << " 次" << endl;
                cout << "方法2的结果是: " << array[i+1] << endl;
                 return  array[i+1];
             }
         }
         return array[0];
        }

        /*
         * 方法3:使用二分法
         */
        int method3MinNumberInRotateArray(vector<int> rotateArray){
                int timeCoculation = 0;
                int front(0),hail(0),mid(0);
                hail = rotateArray.size() - 1;
                //mid = (front+hail)/2;
                while((front+hail)/2!=front){
                    timeCoculation++;
                    // 如果rotateArray[mid] = rotateArray[fron] = rotateArray[hail] 则无法判别是前面数组还是后面数组,故遍历求最小
                    if(rotateArray[(front+hail)/2]==rotateArray[front] ) {
                        int re(2147483647);
                        for (int i = front; i <= hail; ++i) {
                            timeCoculation++;
                            if(re>rotateArray[i])
                                re = rotateArray[i];
                        }
                        cout << "---------------"
                             << endl << "方法3共循环 " << timeCoculation << " 次" << endl;
                        cout << "方法3的结果是: " << re << endl;
                        return re;
                    }
                    if(rotateArray[(front+hail)/2]>rotateArray[hail])
                        front = (front+hail)/2;
                    if(rotateArray[(front+hail)/2] < rotateArray[hail])
                        hail = (front+hail)/2;
                }
            cout << "---------------"
                 << endl << "方法3共循环 " << timeCoculation << " 次" << endl;
            cout << "方法3的结果是: " << rotateArray[hail] << endl;

        }
 };


 int main(){
     vector<int> input_array = {3,4,5,6,2,3,3};
     cout << "测试数据为: ";
     for (int i = 0; i < input_array.size() ; ++i) {
         cout << input_array[i] << " " ;
     }
     cout << endl << "共 " << input_array.size() << " 个数据" << endl;
     Solution re ;
     re.minNumberInRotateArray(input_array);
     re.method2MinNumberInRotateArray(input_array);
     re.method3MinNumberInRotateArray(input_array);
     return 0;

 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值