剑指offer06-旋转数组的最小数

该博客介绍了如何解决在已排序但经过旋转的数组中找到最小元素的问题。提供了三种解题方法,包括暴力法(遍历数组)、解法二(使用二分查找并处理特殊情况)和解法三(通过比较中间元素与右端点来优化)。这些方法的时间复杂度从O(n)到O(log n)不等,其中解法三较为高效。
摘要由CSDN通过智能技术生成

剑指offer06-旋转数组的最小值

一、 题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
题目分析
例如: 1 2 3 4 5 6 7 -->它的旋转数组为4 5 6 7 | 1 2 3,最小值为1
0 1 1 1 1 -->它的旋转数组为1 1 | 0 1 1 ,最小值为0
解题思路: 数组部分有序(前部分递增,后部分也递增),此问题即求后部分数组的开头元素的值,即是整个数组的最小值。
注意:将开头的若干个元素移到末尾,这个若干个也可以是

二、解题方法
2.1 暴力法

此方法不管数组的部分有序性,直接遍历数组。时间复杂度为O(n).

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
    //暴力法
        int len = array.length;
        if(len==0)
            return 0;
        int min = array[0];
        for(int i=0;i<len;i++){
            if(array[i]<min)
                min = array[i];
        }
        return min;
    }
}
2.2 解法二

参考:link ,不太好理解

import java.util.ArrayList;
/**
三种情况:
1)将数组开头的0个元素移到了末尾,即还是原数组
2)mid可以与low和high位置比较大小
3)mid和low和high位置的元素大小相等
*/
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        int len = array.length;
        if(len == 0)return 0;
        int low=0, high=len-1;
        if(array[0] < array[len-1]){return array[0];}//数组本身
        while(low<high){
            int mid = (high+low)/2;
            if((array[mid] == array[low])&&(array[mid]==array[high]))
                return directQuery(array);
            if(array[mid] <= array[high]){high = mid;}
            else if(array[mid]>= array[low]) {low = mid;}
            if(low+1==high)return array[high];
        }
        return -1;
    }
    
    public int directQuery(int [] array){//顺序查找
        int min = array[0];
        for(int num:array){
            if(num<min) min = num;
        }
        return min;
    }
}
2.3 解法三(思想比较好理解,比较简单)

和右端点比较
在这里插入图片描述

import java.util.ArrayList;

public class Solution {
    public int minNumberInRotateArray(int [] array) {
        int len = array.length;
        if(len == 0)return 0;
        int low = 0, high = len-1;
        if(array[0]<array[len-1])return array[0];//是原数组,没有移动过
        while(low < high){
            int mid = (low+high)/2;
            if(array[mid] > array[high]){
                //表明min肯定在[mid+1,high]之间
                low = mid + 1;
            }else if (array[mid] < array[high]){
                //表明min肯定在[low,mid]之间
                high = mid;
            }else {
                high--;
            }
        }
        return array[high];
    }
}

和左端点比较

import java.util.ArrayList;

public class Solution {
    public int minNumberInRotateArray(int [] array) {
        int len = array.length;
        if(len == 0)return 0;
        int low = 0, high = len-1;
        //if(array[0]<array[len-1])return array[0];//是原数组,没有移动过
        while(low < high){
            int mid = (low+high)/2;
            if(array[mid] > array[low]){
                //表明min肯定在[mid+1,high]之间
                low = mid ;
            }else if (array[mid] < array[low]){
                //表明min肯定在[low,mid]之间
                high = mid;
            }else {
                low++;
            }
        }
        return array[low];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值