#sicily#1641.Binary Searchable

来源:互联网 发布:python thread sleep 编辑:程序博客网 时间:2024/04/30 10:41

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 0