码迷,mamicode.com
首页 > 其他好文 > 详细

旋转数组的最小元素

时间:2014-07-12 15:33:30      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:使用   数据   问题   for   io   代码   


题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{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
****************************************************************/

旋转数组的最小元素,布布扣,bubuko.com

旋转数组的最小元素

标签:使用   数据   问题   for   io   代码   

原文地址:http://www.cnblogs.com/jing77jing/p/3839766.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!