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