06-旋转数组的最小数字

知识点:数组、二分查找

一、题目描述

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

二、解题思路:

1:暴力解法:初始化最小值为旋转数组的第一个元素,然后遍历数组,并比较大小,遍历完后便可找到最小值。

C++:

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {//输入的数组是原数组的旋转数组,原数组是个非递减排序的数组
        //遍历数组元素,逐个比较大小,最后找到最小值
        int len = rotateArray.size();
        if (len == 0){
            return 0;
        }
        
        int min = rotateArray[0];//初始化最小值为数组的第一个元素
        for(int i=1; i<len; i++){
            if(min > rotateArray[i]){
                min = rotateArray[i];
            }
        }
        
        return min;
        
    }
};

 python2.7.3:

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        length = len(rotateArray)
        if length==0:
            return 0
        
        min_val = rotateArray[0]
        for val in rotateArray:
            if val < min_val:
                min_val = val
        return min_val

2:旋转数组的特点:旋转后前面是个递增的子序列,后面也是个递增的子序列,中间的那个元素就是最小值,所以遍历数组,依次比较前后两个元素大小。

c++: 

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int length = rotateArray.size();
        if(length == 0){
            return 0;
        }
        for(int i=0; i<length; i++){
            if(rotateArray[i] > rotateArray[i+1]){
                return rotateArray[i+1];
            }else{
                continue;
            }
        }
    }
};

 python2.7:

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        length = len(rotateArray)
        if length == 0:
            return 0
        for i in range(length):
            if rotateArray[i] > rotateArray[i+1]:
                return rotateArray[i+1]
            else:
                continue

3:二分法查找:设置两个指针pre和last,分别指向旋转数组的第一个元素和最后一个元素,然后求出中间元素。先比较中间元素与最后一个元素的大小,若中间元素大于最后一个元素,说明最小值在区间[mid,last]之间,更新pre指针,pre = mid+1; 若中间元素小于最后一个元素,则说明最小值在区间[pre,mid]之间,但中间元素也可能是最小值,更新last指针,last = mid,而不是mid-1。

非递减排序,也有可能中间元素和最后一个元素相等,此时更新last,last = last-1。

C++: 

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int length = rotateArray.size();
	    if (length == 0)
		    return 0;
        
	    int pre = 0;//第一个元素下标
	    int last = length - 1;//最后一个元素下标
	    while (pre < last){
            int mid = (pre + last) / 2;
            //case1:当中间元素 大于 最后一个元素,说明最小值在右半区间,则更新pre
            if (rotateArray[mid] > rotateArray[last]){
                pre = mid + 1;
            }
            //case2:当中间元素小于最后一个元素,说明最小值在左半区间
            //但是中间这个元素,可能就是最小值,因此是 last=mide,而不是一般的last=mid-1
            else if (rotateArray[mid] < rotateArray[last]){
			    last = mid;
		    }
            //case3://当中间元素 等于 最后一个元素,说明有重复元素,将区间缩小一个
            else {
			    last = last - 1;
		    }
        }
        return rotateArray[pre];
        
    }
};

 python2.7:

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        length = len(rotateArray)
        begin,end = 0,length-1
        
        while begin < end:
            mid = (begin + end) // 2
            if rotateArray[mid] > rotateArray[end]:
                begin = mid + 1
            elif rotateArray[mid] < rotateArray[end]:
                end = mid
            else:
                end -= 1
        return rotateArray[begin]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值