题目的意思很简单,比如说有数组[1,6,9,2,1,5,15,20],那么满足上述条件的元素为1,15,20。
分析1.
暴力的方法就是从左到右进行遍历,到达某个数字后,在从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);
}
分析2.
如果我们在从左到右扫描数组的时候,能够维护一个candidate的数组, 该数组的元素满足: 到目前为止,这些元素都大于等于它前面的元素,而小于等于到目前为止扫描到的它右边的所有元素。 容易证明, candidate数组中的元素是按照非递减顺序排列的,即对任意的i<j有cand[i] <= cand[j].
当我们扫描到一个小的元素的时候,需要从右到左(从大到小)的判断cand数组中的元素是否还满足条件,知道找到第一个不大于当前扫面元素的cand.
下面是算法的实现:
如果我们在从左到右扫描数组的时候,能够维护一个candidate的数组, 该数组的元素满足: 到目前为止,这些元素都大于等于它前面的元素,而小于等于到目前为止扫描到的它右边的所有元素。 容易证明, candidate数组中的元素是按照非递减顺序排列的,即对任意的i<j有cand[i] <= cand[j].当我们扫描到一个小的元素的时候,需要从右到左(从大到小)的判断cand数组中的元素是否还满足条件,知道找到第一个不大于当前扫面元素的cand.
下面是算法的实现:
- int findNum(int *arr, int n)
- {
- if(arr == NULL) return 0;
- int *cand = new int[n];
- int idx = 0; //记录当前cand数组中的元素个数。
- cand[idx++] = arr[0];
- int max = arr[0], i;
- for(i=1; i<n; i++) {
- if( arr[i] >= max) {
- cand[idx++] = arr[i];
- max = arr[i];
- } else {
- while(idx > 0 && cand[idx-1] > arr[i]) idx--;
- }
- }
- printf(" num: ");
- for(i=0; i<idx; i++) printf("%d ", cand[i]);
- printf("\n");
- return idx;
- }
- int main()
- {
- int arr[20] = {3, 1, 6, 4, 5, 7, 9, 8, 10, 14, 12};
- //int arr[20] = {1, 2, 4, 5, 6, 7, 8, 9, 10, 3, 11};
- int count = 0;
- count = findNum(arr, 11);
- }