您的位置:首页 > 职场人生

算法面试题,在数组中找出这样的数,它比它前面的数都大,比它后面的数都小

2014-07-17 12:51 399 查看
问题:在一个数组A
中,找出所有这样的A[i],它比它前面的所有数都要大,比它后面的数都要小

例如:如果A[8] = {1 2 3 4 5 6 7 8},则输出 1 2 3 4 5 6 7 8

            如果A[8] = {8 7 6 5 4 3 2 1},则输出为空
            如果A[8] = {3 5 4 2 1 6 8 7},则输出为6

这里给出四种方法,所有方法中,beg指向数组第一个元素,end指向数组中最后一个元素。

方法一:暴力搜索法

对每一个元素,判断它是否比它前面的数都大,然后判断它是否比它后面的数都小

void ViolentWay(int *beg, int *end){
if(beg == end){
cout<<*beg<<end;
return;
}
int *cur;
for(cur = beg; cur<=end; ++cur){
int *temp;
for(temp = beg; temp<cur; ++temp){<span style="white-space:pre">	</span>//与前面的数进行比较
if(*temp > *cur){
break;
}
}
if(temp != cur){<span style="white-space:pre">	</span>// 如果是中途break出来的,则 temp!=cur ,这时要continue,对下一个数进行判断
continue;
}
for(temp=cur+1; temp<end+1; ++temp){<span style="white-space:pre">	</span>// 与后面的数进行比较
if(*temp < *cur){
break;
}
}
if(temp == end+1){<span style="white-space:pre">	</span>// 两个循环安全走完,复合要求
cout<<*cur<<' ';
}
}
cout<<endl;
}
方法二:排序辅助法
这种方法不可行,请直接忽略!!!

对于原先的数组A
,申请一个新的数组B
,B
存放A
排序后的结果。对应位置上A[i]==B[i],则输出。

void SortWay(int *beg, int *end){
if(beg == end){
cout<<*beg<<end;
return;
}

int Size = end-beg+1;
int *Low = new int[Size];<span style="white-space:pre">	</span>// 申请内存空间
int *High = Low;

int *temp;
for(temp=beg; temp<=end; ++temp){<span style="white-space:pre">	</span>// 数组复制
*High++ = *temp;
}
sort(Low, High);<span style="white-space:pre">		</span>// 排序

for(temp=beg, High=Low; temp<=end; ++temp,High++){
if(*temp == *High){
cout<<*temp<<' ';
}
}
cout<<endl;
delete[] Low;
}
方法三:“查找表”法
构造一个“查找表” Min
;对应位置上Min[i],存放了原数组A[i]位置往后这一部分的最小值。

一个变量Max,保存了在遍历A
时,遇到的最大值。

遍历A
,如果 A[i]>=Max (比前面的数都大),并且 A[i] <= Min[i] (比后面的数都小),输出A[i].

void LookupWay(int *beg, int *end){
if(beg == end){
cout<<*beg<<end;
return;
}

int Size = end-beg+1;
int *Min = new int[Size];
int *pcur, *pM;

*(Min+Size-1) = *end;
for(pcur=end-1, pM=Min+Size-2; pcur>=beg; --pcur, --pM){
*pcur<*(pM+1)? *pM=*pcur : *pM=*(pM+1);		// 构造“查找表”
}

int Max=*beg;
for(pcur=beg, pM=Min; pcur<=end; ++pcur, ++pM){
if(*pcur > Max){					// 修改“当前对象前面部分的最大值”
Max = *beg;
}
if(*pcur >= Max && *pcur <= *pM){		// 判断是否符合条件
cout<<*pcur<<' ';
}
}
cout<<endl;

delete[] Min;
}


四:快速搜索法
在数组中,找到最小值的地址(指针、索引)MinIndex,则

1、如果MinIndex 指向最后一个元素,则原数组中所有元素均不满足,return;

2、如果MinIndex 指向第一个元素,则第一个元素满足要求,输出。

3、如果MinIndex 指向中间的某个元素,则对后半部分,递归进行上面的过程。

在上述算法中,需要设置一变量Max,保存MinIndex 前面一部分的最大值。

下面是算法的实现,已经将递归算法改为循环了。

int *FindMax(int *beg, int *end){
int *Index = beg;
int *temp;
for(temp = beg; temp <=end; ++temp){
if(*temp >= *Index){
Index = temp;
}
}
return Index;
}
int *FindMin(int *beg, int *end){
int *Index = beg;
int *temp;
for(temp = beg; temp <=end; ++temp){
if(*temp <= *Index){
Index = temp;
}
}
return Index;
}
void QuickWay(int *beg, int *end, int Max=0xf0000000){<span style="white-space:pre">	</span>//Max 最大值初始化为最大负数值
if((beg == end)&&(*beg >= Max)){
cout<<*beg<<endl;
return;
}
int *MaxIndex, *MinIndex;
while(true){
MinIndex = FindMin(beg,end);<span style="white-space:pre">		</span>// 找到最小值的索引
MaxIndex = FindMax(beg, MinIndex);<span style="white-space:pre">	</span>// 找到MinIndex 前面一部分的最大值
if(*MaxIndex > Max){
Max = *MaxIndex;
}
if(end == MinIndex ){<span style="white-space:pre">			</span>// MinIndex 指向最后一个元素时,就可以break了,但最后一个元素也可能符合要求
if(*end >= Max){
cout<<*end;
}
break;
}
else if((beg == MinIndex)&&(*MinIndex >=Max)){<span style="white-space:pre">		</span>// MinIndex 指向第一个元素,如果它比Max大,则符合要求
cout<<*MinIndex<<' ';
}
beg = MinIndex + 1;
}
cout<<endl;
}

方法空间复杂度时间复杂度(最好)时间复杂度(平均)时间复杂度(最坏)
暴力搜索O(1)O(N^2)O(N^2)O(N^2)
排序辅助法O(N)O(N)O(NlogN)O(N^2)
查找表O(N)O(N)O(N)O(N)
快速搜索O(1)O(N)O(NlogN)O(N^2)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试题 算法 c++
相关文章推荐