求数组中比左边元素都大同时比右边元素都小的元素
求数组中比左边元素都大同时比右边元素都小的元素,返回这些元素的索引
要求时间复杂度 O(N)。比如:
输入:[2, 3, 1, 8, 9, 20, 12]
输出:3, 4
解释:数组中 8, 9 满足题目要求,他们的索引分别是 3、4
解析: 对于数组中每个元素,如果它比左侧最大值要大,比右侧最小值要小,就满足条件; 所以可以定义两个数组maxLeft、minRight,分别存储第i个元素左侧的最大值和右侧最小值,则可以通过 maxLeft[i] < arr[i] && minRight[i] > arr[i]来判断。 时间复杂度为O(N)
代码:
void test(int a[],int length){
// 左边最大值
int maxLeft[length];
maxLeft[0] = a[0];
for (int i = 1; i < length - 1; i ++) {
maxLeft[i] = MAX(a[i - 1], maxLeft[i - 1]);
}
// 右边最小值,数组
int minRight[length];
minRight[length - 1] = a[length - 1];
for (int i = length - 1 - 1; i > 0; i --) {
minRight[i] = MIN(minRight[i + 1], a[i + 1]);
}
// 循环
for (int i = 0; i < length; i ++) {
if (a[i] > maxLeft[i] && a[i] < minRight[i]) {
printf("%d\n", i);
}
}
}
优化:
以上分析中的左边最大值,可以不必开辟数组,可以定义一个变量随循环进行计算,优化后代码如下:
void test1(int a[],int length){
// 左边最大值
int maxLeft = a[0];
// 右边最小值,数组
int minRight[length];
minRight[length - 1] = a[length - 1];
for (int i = length - 1 - 1; i > 0; i --) {
minRight[i] = MIN(minRight[i + 1], a[i + 1]);
}
// 循环
for (int i = 0; i < length; i ++) {
if (i > 0) {
// 更新左边最大值
maxLeft = MAX(maxLeft, a[i - 1]);
}
if (a[i] > maxLeft && a[i] < minRight[i]) {
printf("%d\n", i);
}
}
}