在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数。
题目的意思很简单,比如说有数组[1,6,9,2,1,5,15,20],那么满足上述条件的元素为1,15,20。
暴力的方法就是从左到右进行遍历,到达某个数字后,在从0开始遍历到当前下标,找出最大的,再从当前下标遍历到尾,找出最小的,然后根据题意比较一下,这个算法为O(n^2)。
比较简单的算法就是利用一下额外的空间,保存一下,每个元素右侧的最小值,或者左侧的最大值,在反向遍历一次。举个例子。
就如[1,6,9,2,1,5,15,20],如果我们要找到该数组右侧的最小值,则从后向前遍历,20开始,20的右侧的最小值为20,之后15,15右侧的最小值为15,之后5,最小值为5,之后1,最小值为1,那么新的数组就是[1,1,1,1,1,5,15,20]。
之后我们再从左向右遍历数组,并保存当前的最大值,到1,最大值为1,看新的数组,右侧的最小值为1,那么1>=1,1<=1,满足,输出,对于6,更新最大值为6,看新数组6右边的最小值为1,6>=6,但是>1,也就是比右侧最小的值大,不满足条件,不输出。同理遍历一遍就好。
代码如下:
#include <iostream> #include <assert.h> using namespace std; void FindValue(int a[], int size) { assert(a!=NULL); assert(size!=0); // 定义一个辅助数组 int* b = new int[size]; int min=a[size-1]; for(int i=size-1; i>=0 ; i--) { if(a[i]<=min) { min = a[i]; } b[i] = min; } int max = a[0]; for(int i=0; i<size; i++) { if(max <= a[i]) max = a[i]; if(a[i]>=max && a[i]<= b[i]) cout<<a[i]<<endl; } delete[] b; } int main() { int a[]={1,6,9,2,1,5,15,20}; int size = sizeof(a)/sizeof(a[0]); for (int i=0; i<size; i++) { cout<<a[i]<<" "; } cout<<"\n满足要求的元素为:\n"; FindValue(a,size); }