我投的岗位是测试开发,有两道编程题,第一题是求函数最宽尖峰。第二题笔试的时候没来得及做,现在找不到题目了。把第一题总结一下吧。
函数最宽上升下降区间
1、函数最宽尖峰
给出一个数字组成的数列,相邻的数字是严格单调递增或者严格单调递减的(也就是说相邻的数不相等)。一个数如果比它左右两边的都大,称为一个尖峰。求该数列中最宽的尖峰的底部的坐标。若没有尖峰,则返回(-1,-1)
思路:
设len为尖峰两个底部之间的距离。low为左底部,high为右底部。ret[2]纪录返回值。
1)遍历数组,
判断a[i]是否为尖峰(如果a[i]比它前一个数大,比它后一个数小,则a[i]为尖峰);
2)找到尖峰后,向左循环找到尖峰左底部,纪录其坐标为low(向左应该是单调增的,也就是a[low - 1] < a[low],若不满足单调递减了,就到了峰底)
同理,向右找到尖峰右底部high。可求出次尖峰宽带为distance = high - low;
3)如果len<distance,更新len的大小,并将low和high的坐标付给ret数组。
代码:
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
int n;//数组长度
cin >> n;
vector<int> a;
int num = 0;
for (int i = 0; i < n ; ++i)
{
cin >> num;
a.push_back(num);
}
int ret[] = {-1, -1};
int len = 0;
int low = 0;
int high = 0;
for (int i = 1; i < n - 1; ++i)
{
if (a[i] > a[i-1] && a[i] > a[i + 1]){
low = i - 1;
high = i + 1;
while(low >= 1){
if(a[low - 1] < a[low]){//
low --;
}
else
break;
}
while(high < n - 1){
if(a[high] > a[high + 1] ){
high ++;
}
else
break;
}
if(high - low > len){
len = high - low;
ret[0] = low;
ret[1] = high;
}
}
}
cout << ret[0] << " " << ret[1];
return 0;
}
后来看到另外一种思路,遍历数组,记录所有的峰底。然后找出相邻峰底之差最大的即所求。
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
int n;//数组长度
cin >> n;
vector<int> a;
int num = 0;
for (int i = 0; i < n ; ++i)
{
cin >> num;
a.push_back(num);
}
vector<int> ret;
ret.push_back(-1);
ret.push_back(-1);
int len = 0;
int left = 0;
int right = 0;
vector<int> bottom;
for(int i = 1; i < n - 1; i ++){
if(i == 1){
if(a[0] < a[1])
bottom.push_back(0);
}
if(i == n-1){
if(a[i] > a[n-1])
bottom.push_back(n-1);
}
if(a[i] < a[i - 1] && a[i] < a[i + 1]){
bottom.push_back(i);
}
}
//遍历bottom,求相邻的差最大的两个数
for (int i = 1; i < bottom.size(); ++i)
{
int distance = bottom[i] - bottom[i - 1];
if(distance > len){
len = distance;
ret[0] = bottom[i - 1];
ret[1] = bottom[i];
}
}
cout << ret[0] << " " << ret[1];
return 0;
}