逻辑类
每天记录一些自己算法,也可以和大家一起讨论提高
题目:接雨水问题:
暴力求解就是指,从前向后遍历,在for循环里继续进行嵌套循环,比较,然后进行雨水的计算;这样时间复杂度很高
这里取巧的方法是利用分层求解的方式:
从下到上,每一层进行计算;
layer=1:左指针向后,为0,++;右指针往前,为0,–;然后遍历左指针和右指针中间的区域,为0的地方,雨水++;
对第一层数据为0的部分+1;
layer=2:左指针向后,为1,++,右指针往前,为1,–;然后遍历左指针和右指针中间的区域,为1的地方,雨水++;对第二层的数据为1的部分+1;
……
按照这样的方式就可以求出最终的雨水存储量
代码如下:简洁易懂
public static int maxRainyNum(int num[]){
//最大的层数
int rainy = 0;
int low =0,high = num.length-1;
int layer = 0;
while (low < high){
while (num[low] == layer) low++;
while (num[high] == layer) high--;
for (int i = low; i <= high; i++) {
if(num[i] == layer) {
rainy++;
//进行一下覆盖,以便下一次寻找
num[i] = layer + 1;
}
}
//下一层:layer++
layer++;
}
return rainy;
}
华为笔试中一道类似的题,求最大连通的矩形面积
也是利用分层的思想:
第一层里面求一个最大的矩形面积,第二层里面继续按照类似的方法求矩形面积
直到找到最大连通的矩形面积,
这里和上面不同的是,矩形需要连通,所以这里low和high之间有可能会进行多次遍历
另外上一层的矩形面积和下面几层的面积是相关的。
//求layer的最大值
public static int maxlayer(int num[]) {
int max = 0;
for (int i = 0; i < num.length; i++) {
if (num[i] > max) max = num[i];
}
return max;
}
//接雨水问题的扩展,可以换成求最大的连续矩形的面积
public static int maxSqire(int num[]) {
int max = 0;
int maxlayer = maxlayer(num);
for (int i = 1; i <= maxlayer; i++) {
//每一层,以layer分割计算最大的连续矩形的面积值
int maxcount = maxcontinue(num, i, 0, num.length - 1);
if(max < maxcount) max = maxcount;
}
//计算每一层的最大值,进行比较即可
return max;
}
//以layer进行分割,求连续的最大值
public static int maxcontinue(int[] num,int layer,int low,int high){
int maxcount =0;
int max =0;
while (low<high){
maxcount = 0;
while (num[low] <layer) low++;
while (num[high] <layer) high--;
while (low <= high && num[low] >= layer ) {
maxcount+=layer;
low++;
}
if(max < maxcount) max = maxcount;
}
return max;
}
```time:9/15