363. Max Sum of Rectangle No Larger Than K ,由之引申出的三个问题

363. Max Sum of Rectangle No Larger Than K ,由之引申出的三个问题

目录

本Markdown编辑器使用[StackEdit][6]修改而来,用它写博客,将会带来全新的体验哦:
- 最大子数组和
- <=k最大连续子数组和
- 2d到1d的转化


最大连续子数组和

LC 53题,这里采用了Kadane算法 , 核心思路是dp,在每一个点记录包含该点的最大连续子数组,所以有两种选择;
1.dp[i-1] >0 ,则dp[i] = dp[i-1] + a[i];
2.dp[i-1]<=0,则dp[i] = a[i];
每一步更新一下结果值
time : O(n^2)


<=k最大子数组和

给定一个数组 int[] a ,和 k,求值小于等于k的最大连续子数组和。

自然会联想到上一题,但在上一题中,所有小于0的数组都可以不要,这里因为有限制,当我们遇到一个k+1的时候,我们期望前面能找到一个和为-1的数组来组成最大值,所以小于0的值需要保留,之前的方法不够;
这里采用一个TreeSet,对于之前的所有sum我们都存入treeset,对于一个新遇到的sum1,我们期望有一个 sum2 , 满足:
1.sum1-sum2 <= k
2.sum1-sum2 最大
综上我我们需要在treeset里找一个 s>=sum1-k 的最小sum2;
这里采用一个 treeset.ceiling(sum1-k)就可以得到;注意判断null


2d到1d的转化

至此我们已经完成了1d情况下问题的解法,那这一步就可以把原问题转化成2d;
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2

以此为例,如果在竖直方向累加,可以将多行合成一个数组,那也就变成了我们上一题的问题,此时每个子数组也就是一个矩形。 此时在竖直方向需要循环两层, O(row ^ 2) ,在水平方向上就是上面的复杂度 , O(col * log(col))
可以发现row是复杂度的核心地区,为了增加速度,我们预处理矩阵,将最短的方向作为竖直,之后再进行相应的计算
time:
m i n ( m , n ) 2 m a x ( m , n ) l o g ( m a x ( m , n ) )

Error:

最新一次刷题遇到一些问题:
1.整体思路有,结果在<=k最大子数组和这个部分卡住了,忘记了用TreeSet来操作;这里总结一下,对于已有范围和期望值的范围,可以通过treeset来实现O(logN)的最优值查找;
2.一开始在每一行内都重新计算i–j行的和,导致复杂度之间多*N非常的傻,很明显每一步我们是知道了(i,j-1)行的值,只需要在这个基础上加a[j][x]就知道当前位置的sum了。
3.注意每个sum使用之后都要放到TreeSet

猜你喜欢

转载自blog.csdn.net/qq_24436311/article/details/81288881