曾经在力扣评论区看见这样一句话,“sort函数就是简单题的爹”,这里就直接用sort函数,使用lambda表达式写比较器,按箱子能装的最大数量排序,先选最大的箱子,贪心的思想
class Solution {
public int maximumUnits(int[][] boxTypes, int truckSize) {
Arrays.sort(boxTypes,(o1,o2)->o2[1]-o1[1]);
int res=0;//结果
int index=0;//指向最大的箱子
while(truckSize>0&&index<boxTypes.length){
if(truckSize>=boxTypes[index][0]){
truckSize-=boxTypes[index][0];
res+=boxTypes[index][1]*boxTypes[index][0];
index++;
}
else{
res+=boxTypes[index][1]*truckSize;
truckSize=0;
}
}
return res;
}
}
前缀和:
昨天写到了二维数组前缀和的问题,现在系统复习一下,首先是一维数组,前缀和的作用就是为了方便求区域和
如数组 1,2,3,4,5,6
对应前缀和 1,3,6,10,15,21
不难发现前缀和的计算就是前一个前缀和加上当前数字,前缀和主要用来解决区间和问题,比如这里2,4区间的和,就可以用15-3即sum【4】-sum【2-1】的值,i,j就是sum【j】-sum【i-1】利用小学知识就很容易理解,但是要注意这里比如0-2区间的和,就不能sum【2】-sum【0-1】,其实就是sum【2】的值,还有一种前缀和的写法是前缀和保存前面几个数的和,这里就是 0,1,3,6,10,15,21,这样i,j就是sum【j+1】-sum【i】,就不要判断0的情况,力扣中对应前缀和的题:
直接附上代码:
class NumArray {
int[] sum;//保存前缀和
public NumArray(int[] nums) {
this.sum=new int[nums.length];
sum[0]=nums[0];
for(int i=1;i<nums.length;i++){
sum[i]=sum[i-1]+nums[i];
}
}
public int sumRange(int left, int right) {
if(left==0) return sum[right];
return sum[right]-sum[left-1];
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* int param_1 = obj.sumRange(left,right);
*/
二维前缀和:
一维前缀和用的是小学计算知识,那么二维就是用的小学几何知识
首先初始化,sum[0][0]一定是等于arr[0][0]的,
然后第一行和第一列,可以看做一维数组的前缀和分析
不是第一行和第一列的,利用几何分析,当前位置就是一个大矩形,上面的矩形加下面的,加上当前值,再减当前值,就是该大矩形面积
在任意一个位置矩形时,除了等于0时的特殊位置,都可以用大矩形去减,再加上重复区域,语言表达有点困难,需要使用时还是需要画图理解。
class NumMatrix {
int[][] sum;
public NumMatrix(int[][] matrix) {
int m=matrix.length;
int n=matrix[0].length;
sum=new int[m][n];
sum[0][0]=matrix[0][0];
for(int i=1;i<m;i++){
sum[i][0]=sum[i-1][0]+matrix[i][0];//第一列
}
for(int j=1;j<n;j++){
sum[0][j]=sum[0][j-1]+matrix[0][j];//第一行
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
sum[i][j]=sum[i-1][j]+sum[i][j-1]+matrix[i][j]-sum[i-1][j-1];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
if(row1==0&&col1==0) return sum[row2][col2];
if(row1==0) return sum[row2][col2]-sum[row2][col1-1];
if(col1==0) return sum[row2][col2]-sum[row1-1][col2];
return sum[row2][col2]-sum[row2][col1-1]-sum[row1-1][col2]+sum[row1-1][col1-1];
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/
来个二维数组前缀和的应用,基本就是把上题的代码粘贴过去,但是这里列举了所以矩形的左上角和右下角,用了四层循环,ac是ac了,但是就差那么一点就垮了,毕竟是困难题,纯用前缀和应该是不可能的,这里暴力ac了属于侥幸了
class Solution {
int[][] sum;
public int maxSumSubmatrix(int[][] matrix, int k) {
int m=matrix.length;
int n=matrix[0].length;
sum=new int[m][n];
sum[0][0]=matrix[0][0];
for(int i=1;i<m;i++){
sum[i][0]=sum[i-1][0]+matrix[i][0];//第一列
}
for(int j=1;j<n;j++){
sum[0][j]=sum[0][j-1]+matrix[0][j];//第一行
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
sum[i][j]=sum[i-1][j]+sum[i][j-1]+matrix[i][j]-sum[i-1][j-1];
}
}
int max=Integer.MIN_VALUE;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
for(int a=m-1;a>=i;a--){
for(int b=n-1;b>=j;b--){
int num=sumRegion(i,j,a,b);
if(num<=k){
max=Math.max(num,max);
}
}
}
}
}
return max;
}
public int sumRegion(int row1, int col1, int row2, int col2) {
if(row1==0&&col1==0) return sum[row2][col2];
if(row1==0) return sum[row2][col2]-sum[row2][col1-1];
if(col1==0) return sum[row2][col2]-sum[row1-1][col2];
return sum[row2][col2]-sum[row2][col1-1]-sum[row1-1][col2]+sum[row1-1][col1-1];
}
}