給定一個數組序列,找出這樣的一個資料,資料的左邊的值小於這個數,右邊的值大於這個數。
下午快下班看的題,路上沒事想想,回家陪老婆聊完天,突然想出來了。
演算法思路很簡單的,在開闢一個數組,然後排序,再與原數組比較,相等那個元素就可能是題目所要求的那個資料。
上代碼:
#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;
兩行。