前缀和数组

一、区域和检索-数组不可变

class NumArray {
    private int preSum[];
    public NumArray(int[] nums) {
        //构建前缀和数组
        preSum=new int [nums.length+1];
        // preSum[0] = 0,便于计算累加和 
        preSum[0]=1;     
        for(int i=1;i<nums.length+1;i++){
            preSum[i]=preSum[i-1]+nums[i-1];
        }
    }
    //查询闭区间 [left, right] 的累加和
    /*
     *例如球2,4区间内的和   preSum[4+1]:0,1,2,3,4下标的和
     *                     preSum[2]:0,1
     * 两个一减则为下边2,3,4之和
     */   
    public int sumRange(int left, int right) {
        return preSum[right+1]-preSum[left];
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(left,right);
 */  

二、和为K的子数组

class Solution {
    public int subarraySum(int[] nums, int k) {
        // map:前缀和 -> 该前缀和出现的次数
        HashMap<Integer,Integer> preSum=new HashMap<>();
        preSum.put(0,1);
        int res=0;
        int n=nums.length;
        int sum_i=0;
        for(int i=0;i<n;i++){
            sum_i+=nums[i];

            //这是我们想找的前缀和nums[0..j]
            int sum_j=sum_i-k;
            //如果前面存在这个前缀和,则答案直接更新
            if(preSum.containsKey(sum_j)){
                res+=preSum.get(sum_j);
            }

            //把前缀和nums[0..i]加入并记录出资按的次数
            //如果没出现过则直接设置为1,若出现过则直接个原来的次数加一
            //getOrDefault:如果map中含有sum_i则这个函数值取它原本的值,如果没有则取0
            preSum.put(sum_i,preSum.getOrDefault(sum_i,0)+1);            
        }
        return res;
    }
}
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值