#sicily#1641.Binary Searchable

source:http://soj.sysu.edu.cn/show_problem.php?pid=1005&cid=2390

题意

给出一个序列,找出满足下列条件的数的数目:
1.这个数它比左边的数都大
2.这个数比它右边的数都小

算法

最简单的方法

就是写两个函数,返回index左边最大的数和index右边最小的数,然后和arr[index]比较。满足上述条件则计数+1.

bool findMax(int index)  
{  
    for(int i = 0; i < index; i++)  
    {  
        if(arr[i] > arr[index])  
            return false;  
    }  
    return true;  
}  

bool findMin(int index)  
{  
    for(int i = index + 1; i < v.size(); i++)  
    {  
        if(arr[i] < arr[index])  
            return false;  
    }  
    return true;  
}  

这是最直观的方法,但是复杂度高,达到o( n2 ),让人不满意。

优秀的改进方法

用两个数组分别记录index左边最大的数和index右边最小的数。
分别用两个循环就可以,找出每一个index左边最大的数,和每一个index右边最小的数。
然后再用一次循环来计数,就可以得到结果。
复杂度为o(n);

注意

这里因为题目没有说序列中的数的范围,所以逻辑的最小值要足够小和逻辑最大值要足够大。

优秀改进方法源代码

#include <iostream>
#include <algorithm>

using namespace std;

// 输入的数字序列
int arr[105];
// 记录index右边的最小值
int rightLeast[105];
// 记录index左边的最大值
int leftBiggest[105];

void findRightLeast(int len) {
    // 逻辑最大值
    rightLeast[len-1] = 999999;
    for(int i = len - 2; i > -1; i--) {
     rightLeast[i] = min(arr[i+1], rightLeast[i+1]);
    }
}
void findLeftBiggest(int len) {
    // 逻辑最小值
    leftBiggest[0] = -999999;
    for(int i = 1; i < len; i++) {
        leftBiggest[i] = max(arr[i-1], leftBiggest[i-1]);
    }
}

int main() {
    int len;
    while(cin >> len) {
        // 读入
        for(int i = 0; i < len; i++) {
            cin >> arr[i];
        }

        // 寻找index左边最大值和index右边最小值
        findLeftBiggest(len);
        findRightLeast(len);

        // 计数
        int num = 0;
        for(int i = 0; i < len; i++) {
            if(arr[i] > leftBiggest[i] && arr[i] < rightLeast[i]) {
                num++;
            }
        }
        cout << num << endl;
    }

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值