4.5
技巧:前缀和(适用于快速、频繁地计算一个索引区间内的元素之和)
class NumArray {
private int [] preSum;//前缀和数组
public NumArray(int[] nums) {
preSum=new int[nums.length+1];
for(int i=1;i<preSum.length;i++){
preSum[i]=preSum[i-1]+nums[i-1];
}
}
public int sumRange(int left, int right) {
return preSum[right+1]-preSum[left];
}
}
class NumMatrix {
private int preSum[][];
public NumMatrix(int[][] matrix) {
int m=matrix.length;
int n=matrix[0].length;
preSum=new int[m+1][n+1];
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
preSum[i][j]=preSum[i][j-1]+preSum[i-1][j]+matrix[i-1][j-1]-preSum[i-1][j-1];//将每个方框中的元素放到对应数组右下角位置
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
return preSum[row2+1][col2+1]-preSum[row2+1][col1]-preSum[row1][col2+1]+preSum[row1][col1];
}
}
public int subarraySum(int[] nums, int k) {
int preSum=0;//前缀和
HashMap<Integer,Integer>map=new HashMap<>();
map.put(0,1);
int result=0;
for( int num:nums){
preSum+=num;//求前缀和
int rest=preSum-k;//每次拿着前缀和-k所得的数上map里找,找到的value值就是所求个数
if(map.containsKey(rest)){
result+=map.get(rest);
}
if(map.get(preSum)==null){
map.put(preSum,1);
}else{
int value=map.get(preSum);
map.put(preSum,value+1);
}
//map.put(preSum,map.getOrDefault(preSum,0)+1);
}
return result;
}
4.6
技巧:差分数组(主要适用场景是频繁对原始数组的某个区间的元素进行增减)
class Solution {
public int[] corpFlightBookings(int[][] bookings, int n) {
int []nums=new int[n];
Deference df=new Deference(nums);
for(int []booking:bookings){
int i=booking[0]-1;
int j=booking[1]-1;
int val=booking[2];
df.increase(i,j,val);
}
return df.result();
}
class Deference{//差分数组工具类
private int[]diff;
public Deference(int []nums){
diff=new int [nums.length];
diff[0]=nums[0];
for(int i=1;i<diff.length;i++){
diff[i]=nums[i]-nums[i-1];
}
}
public void increase(int i,int j,int val){
diff[i]+=val;
if(j+1<diff.length){
diff[j+1]-=val;
}
}
public int[]result(){
int[]res=new int[diff.length];
res[0]=diff[0];
for(int i=1;i<res.length;i++){
res[i]=res[i-1]+diff[i];
}
return res;
}
}
}
class Solution {
public boolean carPooling(int[][] trips, int capacity) {
int[]nums=new int[1001];
Deference df=new Deference(nums);
for(int[]trip:trips){
int val=trip[0];
int i=trip[1];
int j=trip[2]-1;
df.increase(i,j,val);
}
int []res=df.result();
for(int i=0;i<res.length;i++){
if(capacity<res[i]){
return false;
}
}
return true;
}
class Deference{
private int[]diff;
public Deference(int []nums){
diff=new int [nums.length];
diff[0]=nums[0];
for(int i=1;i<diff.length;i++){
diff[i]=nums[i]-nums[i-1];
}
}
public void increase(int i,int j,int val){
diff[i]+=val;
if(j+1<diff.length){
diff[j+1]-=val;
}
}
public int[]result(){
int[]res=new int[diff.length];
res[0]=diff[0];
for(int i=1;i<res.length;i++){
res[i]=res[i-1]+diff[i];
}
return res;