美文网首页
LeetCode指北---前缀和&hash

LeetCode指北---前缀和&hash

作者: GableKing黑暗中漫舞 | 来源:发表于2020-04-03 23:14 被阅读0次

    今天搞一个简单的算法

    先上题目:


    没有用前缀 && hash 思想前,我们干撸的代码是这样子的。

       public int subarraySum(int[] nums, int k) {
           // 构造前缀和
           int res =0;
           int tempSum = 0;
           int[] preSum = new int[nums.length+1];
           // 累加和放入数组
           for (int i = 1; i < nums.length+1; i++) {
               tempSum += nums[i-1];
               preSum[i] = tempSum;
           }
           // O^2 遍历,获取的区间和是K的值
           for(int j=nums.length;j>=0;j--) {
              for(int i=0;i<j;i++) {
                  if(preSum[j] - preSum[i] == k) {
                      res +=1;
                  }
              }
           }
           return res;
       }
    
    

    AC,但是结果用时很长,不开心🙃


    那前缀&hash到底是什么,下面是题解代码:

     public int subarraySum(int[] nums, int k) {
            Map<Integer, Integer> map = new HashMap<>();
            map.put(0, 1);
            int sum = 0;
            int ret = 0;
            for(int i = 0; i < nums.length; ++i) {
                sum += nums[i];
                if(map.containsKey(sum-k)) // sum - k <==> j+1 j+2 ... i 子数组和为k  0到j子数组和为sum - k
                    ret += map.get(sum-k);
                map.put(sum, map.getOrDefault(sum, 0)+1);
            }
            
            return ret;
        }
    

    代码里的Map记录的是同样的和出现的次数,对每一个累计和sum,判断map里是否有sum-k

    为什么是sum-k呢,why ???

    仔细想想

    • A[i] = A[0] + A[1] + A[2]+ …… +A[i]

    • A[j] = A[0] + A[1] + A[2]+ …… +A[j]

    如果A[j] - A[i] = A[i+1] + A[i+2] + …… +A[j] = k 的话,从i+1到j是满足条件的一个解把A[i]的值放入map中,当A[j]的值是A[i]+k的话,是满足条件的解,也就是判断一下sum -k 是否已经存在map里,统计符合这样A[j],答案找到了。时间复杂度O(n),AC结果也快了好多。


    趁热打铁,再看一道题:

    思路一致,需要注意的知识点:
    java中负数做取模(%)运算,结果是负数,对应的整数结果应该是k+(sum%k)

      public int subarraysDivByK(int[] A, int K) {
            int res = 0;
            HashMap<Integer, Integer> map = new HashMap<>();
            map.put(0, 1);
            int preSum = 0;
            for (int i = 0; i < A.length; i++) {
                preSum += A[i];
                int temp = preSum % K < 0 ? (K + preSum % K) : preSum % K;
                if (map.containsKey(temp)) {
                    res += map.get(temp);
                }
                map.put(temp, map.getOrDefault(temp, 0) + 1);
            }
            return res;
        }
    

    相关文章

      网友评论

          本文标题:LeetCode指北---前缀和&hash

          本文链接:https://www.haomeiwen.com/subject/gwafphtx.html