给定一个数组序列,找出这样的一个数据,数据的左边的值小于这个数,右边的值大于这个数。
下午快下班看的题,路上没事想想,回家陪老婆聊完天,突然想出来了。
算法思路很简单的,在开辟一个数组,然后排序,再与原数组比较,相等那个元素就可能是题目所要求的那个数据。
上代码:
#include<iostream> using namespace std; const int N=6; void fastSort(int * inputData,int n,int startLoc) { if(n<2) return ;//递归停止的条件 int i=startLoc-1;//指向最后一个小于基元的数据 int j=startLoc;//移动j,挨个遍历元素 int baseDa=inputData[startLoc+n-1];//获取基元 int tmp; int k=0; while(j<=startLoc+n-1) { if(inputData[j]<inputData[startLoc+n-1]||j==startLoc+n-1) { i++; k++; //交换 tmp=inputData[j]; inputData[j]=inputData[i]; inputData[i]=tmp; } j++; } startLoc=i-k+1;//左边分组的位置,右边分组的位置为:i+1 fastSort(inputData,i-startLoc,startLoc); fastSort(inputData,n-(i-startLoc)-1,i+1); } void sort(int * Array,int n) { fastSort(Array,n,0); } int main() { int j; int Array[N]={2,1,3,7,6,5}; int sortedArr[N]; for(int i=0;i<N;++i) { sortedArr[i]=Array[i]; } sort(sortedArr,N); //比较两个数组 for(int i=0;i<N;++i) { if(sortedArr[i]==Array[i]) { if(N-i>=i)//说明i离第0个近 { for( j=0;j<=i;++j) { if(Array[i]<Array[j]) break; //cout<<"第"<<i<<"个元素"<<Array[i]<<"满足条件"; } if(i==j-1) cout<<"第"<<i<<"个元素"<<Array[i]<<"满足条件"; } } //cout<<"第"<<i<<"个元素"<<Array[i]<<"满足条件"; } }
分析:
比如数组:2 1 3 7 6 5
排序后3 和 6位置都没变动。我们先来证明定理:形如数组 x1,x2,x3...xi(i>=1),如果xj(j<=i)比其左边的数大,但比其右边的数小,那么排序后xj的位置不变。
证明:反证法,假设排序后xj的左边的数跟排序之前xj左边的数不一样,显然数组的元素必然变动了。所以定理成立。
也就是说如果我们在排序之后找到位置不变的数就可以确定题目要求的那个数据了。但是其实不然,因为如例子2 1 3 7 6 5里面的6 排序之后位置不变,但是6不满足条件。基于这个原因,我们对原数组再遍历一遍确认一下。如程序
if(Array[i]<Array[j]) break;
两行。