这个题比较简单,好像也比较old,给定一个整数数组A,有N个元素,找到所有下标对(P,Q)满足 0 ≤ P ≤ Q < N 并且 A[P] ≤ A[Q]中最大的Q-P。
数据范围N [1..3*10^5]
数组元素[-10^9, +10^9]
要求时间复杂度O(N),空间复杂度O(N)。
分析: 如果b[i] = max{a[i..N - 1]} ,则对每个i,我们找到最大的j,满足b[j]>=a[i],就可以了。这样做的目的是b,反映了后面还有没有比a[i]大的。注意到假如现在找到的最大差值是r,那么我们只需要j = i + r + 1开始找就可以了,所以j始终是不减少的。循环不变式是j = i + r + 1
代码:
// you can use includes, for example: // #include <algorithm> // you can write to stdout for debugging purposes, e.g. // cout << "this is a debug message" << endl; int solution(vector<int> &A) { // write your code in C++11 int n = A.size(); vector<int> b; b.resize(n); for (int i = n - 1; i >= 0; --i) { b[i] = ((i + 1 < n) && (b[i + 1] > A[i]))?b[i + 1]:A[i]; } int r = 0, j = 0; for (int i = 0; ++j < n; ++i) { for (; (j < n) && (b[j] >= A[i]); ++j) ; r = j - i - 1; } return r; }
代码:
// you can use includes, for example: // #include <algorithm> // you can write to stdout for debugging purposes, e.g. // cout << "this is a debug message" << endl; #include <stack> int solution(vector<int> &A) { // write your code in C++11 stack<int> s; int n = A.size(); s.push(0); for (int i = 1; i < n; ++i) { if (A[i] < A[s.top()]) { s.push(i); } } int answer = 0; for (int j = n - 1; (j >= 0) && (!s.empty()); --j) { while ((!s.empty()) && (A[j] >= A[s.top()])) { answer = max(answer , j - s.top()); s.pop(); } } return answer; }
codility上的问题 (36)Natrium 2014,布布扣,bubuko.com
原文地址:http://blog.csdn.net/caopengcs/article/details/36893725