当修改的val大于当前块的最大值似乎可以优化

来源:2-6 使用 SQRT 分解解决区间最大值最小值问题

Wonwayshon

2021-06-04 14:27:06

考虑到当修改的val大于当前块的最大值就可以直接更新blocks数组来完成更新操作,增加这部分判断似乎会更好一些,自己实现的全部代码如下,也麻烦老师检查一下

import java.util.Arrays;

public class MaxSQRT {
private int[] data,blocks;
private int length;
private int blockSize;
private int blockNum;

public MaxSQRT(int[] nums){
length = nums.length;
if(length==0){
return;
}
data = Arrays.copyOf(nums, length);
blockSize = (int)Math.sqrt(length);
blockNum = length / blockSize + (length % blockSize > 0 ? 1 : 0);
blocks = new int[blockNum];
Arrays.fill(blocks,Integer.MIN_VALUE);
for(int i=0;i<length;i++){
if(data[i]>blocks[i/blockSize]){
blocks[i / blockSize] = data[i];
}
}
}

public int maxRange(int l,int r){
if(l<0 || l>=length || r<0 || r>=length || l>r){
throw new IllegalArgumentException("Illegal l and r!");
}

int startBlock = l / blockSize;
int endBlock = r / blockSize;
int result=data[l];
if(startBlock==endBlock){
for(int i=l;i<=r;i++){
if(data[i]>result){
result = data[i];
}
}
return result;
}
for(int i=l;i<(startBlock+1)*blockSize;i++){
if(data[i]>result){
result = data[i];
}
}
for(int j=startBlock+1;j<endBlock;j++){
if(blocks[j]>result){
result = blocks[j];
}
}
for(int i=endBlock*blockSize;i<=r;i++){
if(data[i]>result){
result = data[i];
}
}
return result;
}

public void update(int index,int val){
int blockIndex = index / blockSize;
data[index] = val;
if(val>=blocks[blockIndex]){
blocks[blockIndex]=val;
}else{
int max=val;
for(int i=blockIndex*blockSize;i<Math.min((blockIndex+1)*blockSize,length);i++){
if(data[i]>max){
max = data[i];
}
}
blocks[blockIndex] = max;
}
}
}


写回答

1回答

liuyubobobo

2021-06-05

麻烦把你增加代码的地方打一个注释?


==========


如果你的 sqrt 分解只是用于求解最大值或者最小值,可以的。但注意,类似的思路不一定适合与所有区间问题,比如不适合于区间和。可以参考这里:https://class.imooc.com/course/qadetail/291641


继续加油!:)

0
hiuyubobobo
回复
honwayshon
hp>我补充在了原回答中。继续加油!:)

h021-06-06
共2条回复

算法与数据结构

波波老师5年集大成之作,算法与数据结构系统学习,考试、面试、竞赛通用

2636 学习 · 1090 问题

查看课程