旋转数组的最小元素

题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数。
输入的第二行包括n个整数,其中每个整数a的范围是(1<=a<=10000000)。
输出:
对应每个测试案例,
输出旋转数组中最小的元素。
样例输入:
5
3 4 5 1 2
样例输出:
1

解题思路:
方法1:顺序查找,找出最小的元素,时间复杂度为O(n),但是空间复杂度为O(1),不需要开辟存放数组的空间。这种方法也能被Accepted.
方法2:利用旋转数组的性质,采用二分查找,利用前半部分和后半部分是递增且后半部分小于前半部分的性质,主要思路是,

while(low != high -1){
    mid = (low + high)/2;
    if(A[low] <= A[mid]){ //如果low所指向的元素比mid所指向的元素要小,说明[low,mid]是递增的数组,要查找的最小值不在这个区间之内
        low = mid;
    }else {  // 要找的数据在low 和 mid 之间
        high = mid;
    }
}

但是,这个问题中有一些特殊情况需要考虑,
情况1:数组是递增的,使用条件A[0]<A[n-1]来判断即可,最小的元素就是A[0]了。
情况2:数组中存在相等的元素,而且处理的方法有多种的情况下,比如对于序列1 0 1 1 1和序列1 1 1 0 1,这二者如果使用以上的方法来处理,会出错,这两者都满足A[low] <= A[mid]但是需要采用不同的low, high变换方法。所以,这种情况,需要特殊考虑,采用顺序查找的方法去处理。

代码如下:

#include<stdio.h>
#include<stdlib.h>

void binarySearch();
void sequentialSearch();

int main(){
    /*binarySearch();*/
    sequentialSearch();
    return 0;
}

void sequentialSearch(){
    int n;
    int min;
    int value;
    while(scanf("%d",&n)!=EOF){
        min = 10000001;
        for(int i=0;i<n;i++){
            scanf("%d",&value);
            if(value<min){
                min = value;
            }
        }
        printf("%d\n",min);
    }
}

void binarySearch(){
    int n;
    int* rotatedArray;
    int low,high,mid;
    while(scanf("%d",&n)!=EOF){
        rotatedArray = (int *)malloc(sizeof(int)*n);
        for(int i=0;i<n;i++){
            scanf("%d",&rotatedArray[i]);
        }
        low = 0;
        high = n-1;
        if(n==1){
            printf("%d\n",rotatedArray[0]);
            continue;
        }
        if(rotatedArray[0]<rotatedArray[n-1]){ //递增序列时,第一个元素最小
            printf("%d\n",rotatedArray[0]);
            continue;
        }

        //对于序列 1 1 1 0 1  和序列 1 0 1 1 1,如果按照如下的处理方法会出错,即两种情况的low和high的变化方法不同,
        //所以,对于low,mid,high三者都相等的情况下,顺序查找
        int min=10000001;
        int minIndex =0;
        mid = (high+low)/2;
        if(rotatedArray[low] == rotatedArray[mid] && rotatedArray[mid] == rotatedArray[high]){
            for(int i = low;i<= high ;i++){
                if(rotatedArray[i]<min){
                    min = rotatedArray[i];
                    minIndex = i;
                }
            }
            printf("%d\n",rotatedArray[minIndex]);
            continue;
        }
        while(low != (high-1)){
            mid = (low+high)/2;
            if(rotatedArray[low]<=rotatedArray[mid]){
                low = mid;
            }else {
                high = mid;
            }
        }
        printf("%d\n",rotatedArray[high]);
    }
}
/**************************************************************
    Problem: 1386
    User: jingxmu
    Language: C++
    Result: Accepted
    Time:660 ms
    Memory:1020 kb
****************************************************************/
二叉查找得到的结果如下:
/**************************************************************
    Problem: 1386
    User: jingxmu
    Language: C++
    Result: Accepted
    Time:650 ms
    Memory:4928 kb
****************************************************************/

旋转数组的最小元素

时间: 2024-12-06 09:28:52

旋转数组的最小元素的相关文章

[经典面试题]输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。

[题目] 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1. [分析] 这道题最直观的解法并不难.从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N).但这个思路没有利用输入数组的特性,我们应该能找到更好的解法. 我们注意到旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后面

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

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. eg: 输入 3 4 5 1 2 输出 1 思路:用二分法查找最小元素 三种情况: (1)rotateArray[mid] >rotateArray[high]: like:[x,x,x,6,x,x,2],此时最小数字一

剑指offer_旋转数组的最小元素

题目:输入递增数组的一个旋转,输出旋转数组的最小元素. /* 解题思路: 1.本题中,最小的元素是被旋转部分数组的第一个元素:采用二分法,当中间值小于数组末尾元素时,说明此中间值处于被旋转 部分数组当中,最小值在左边包含中间值的数组中,high=mid:当中间值大于数组末尾元素时,说明此中间值处于前面 未被旋转的部分数组中:最小值在中间值的右边:low=mid+1; 2.考虑特殊情况:出现重复时,这时使用顺序查找: */ public class Solution { public int mi

程序员面试题目总结--数组(三)【旋转数组的最小数字、旋转数组中查找指定数、两个排序数组所有元素中间值、数组中重复次数最多的数、数组中出现次数超过一半的数】

转!http://blog.csdn.net/dabusideqiang/article/details/38271661 11.求旋转数组的最小数字 题目:输入一个排好序的数组的一个旋转,输出旋转数组的最小元素. 分析:数组的旋转:把一个数组最开始的若干个元素搬到数组的末尾.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1.这道题最直观的解法并不难.从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N).但这个思路没有利用输入数组

旋转数组的最小数字

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size()==0) re

【剑指offer】旋转数组的最小数字

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 分析描述: 求一个数组中的最小值,最简单的办法就是逐个比较数组中各个元素的值,遍历完整个数组,即可得数组中最小元素.但这种方法存在的问题是时间复杂度为O(n). 利用题目中给出的条件:递增排序数组的旋转.利用递增排序的特点,可以用二分查找方法实现时间复杂度为O(logn)的查找.

剑指offer java -查找旋转数组的最小数字

/** * Created by wqc on 2017/7/18. * 查找旋转数组的最小数字 * 把一个数组最开始的若干个元素搬到数组的末尾,称为数组的旋转 * 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素 * 如:3,4,5,1,2 为1,2,3,4,5的一个旋转,最小值为1 */public class Problem8_findMinNumber { public Integer findMinNum(int[] array) { if(array == null) { r

《剑指offer》— JavaScript(6)旋转数组的最小数字

旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 实现代码 function minNumberInRotateArray(rotateArray) { var len=rotateArray.length; if(len== 0 || !r

旋转数组的最小数字 - 剑指offer 面试题8

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if (rotateArray.size() == 0