这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
1936. 新增的最少台阶数
思路分析
看起来是简单的一次遍历但是会在数据量过大的时候,出现问题。
在遇到两个相邻数组元素之间需要插入多个台阶的时候,如果使用如下方式
for(int i = 0; i < rungs.size(); i++){
if(rungs[i] - tmp > dist){
tmp += dist; ret++; i--;
}else{
tmp = rungs[i];
}
}
那么时间复杂度其实就是O(Max(rungs)/dist),当然按照时间复杂度的写法应该是O(Max(rungs)/dist)
在发现超时后我们设法剪枝,使用如下方式将时间复杂度降低
tmp = rungs[i] - rungs[i - 1];
if (tmp > dist){
ret += tmp/dist - 1;
if(tmp % dist != 0)ret++;
}
1937 扣分后的最大得分
思路分析
这道题也是具有很明显的子问题用来求解总问题的特征。我们很容易写出代码
//假装有初始化代码
for(int i = 1; i < m; i++){
for(int j = 0; j < n; j++){
int maxt = -1;
for(int k = 0; k < n; k++){
maxt = max(arr[i - 1][k] - abs(j - k),maxt);
}
arr[i][j] = maxt + points[i][j];
}
}
int maxt = -1;
for(int i = 0; i < n; i++){
maxt = max(maxt, arr[m - 1][i]);
}
但很明显时间复杂度到达了假设m==n,则时间复杂度为,这就导致了超时。那么如何优化呢?
我们可以将
转化为
,很明显,只有在j'小于j的时候,该公式成立,因此,再反向计算一次,比较两次得到的最大值作为答案。
由于公式中表达式右边不存在f[i][k],因此两次计算可以同时计算,互不发生冲突。