题目描述
给定一个整数数组A,坡是元组(i,j),其中i < j且A[i] <= A[j]。这样的坡的宽度为 j - i。找出A中的坡的最大宽度,如果不存在,返回0。
示例1
输入:[6,0,8,2,1,5]
输出:4
解释:最大宽度的坡为(i,j) = (1,5):A[1] = 0 且 A[5] = 5
示例2
输入:[9,8,1,0,1,9,4,0,4,1]
输出:7
解释:最大宽度的坡为(i,j) = (2,9):A[2] = 1 且 A[9] = 1
解题思路
在这里分享一下本菜鸡惨绝人寰的刷题的痛,一开始读完本题,感觉可能是用动态规划处理,于是定义dp[i]是i位置结尾最大宽度的坡,状态转换方程是:A[i] >= A[i-1]时dp[i] = dp[i-1] + 1 ,否则j从i-1一直遍历到0,记录A[j] <= A[i]的最靠前位置tmp,然后dp[i] = i - tmp,最后取max(maxl,dp[i]);但是没有掌握到dp的精髓,卡在[2,1,3]。发现当A[i] >= A[i-1]时,不能直接dp[i] = dp[i-1] + 1,也应该与A[i] < A[i-1]作同样的处理。what?那就变成了O(N2)。再看数据大小一定过不了。。。通过大佬的点拨,正确的解法是将原始序列按大小对索引进行排序(python中的argsort()函数),然后遍历数组,每次记录最小索引的位置,取当前索引减最小索引的差即为宽度。
struct node{
int val;
int idx;
node(int _val,int _idx):val(_val),idx(_idx){}
};
bool cmp(node a,node b){
if(a.val == b.val) return a.idx < b.idx;
return a.val < b.val;
}
class Solution {
public:
int maxWidthRamp(vector<int>& A) {
int len = A.size();
int maxl = 0,idx = len;
vector<node> vect;
for(int i=0;i<len;i++) vect.push_back(node(A[i],i));
sort(vect.begin(),vect.end(),cmp);
for(int i=0;i<len;i++){
maxl = max(maxl,vect[i].idx-idx);
idx = min(vect[i].idx,idx);
}
return maxl;
}
};