zoukankan      html  css  js  c++  java
  • Range Sum Query

    https://leetcode.com/problems/range-sum-query-mutable/

    因为数组会变动,所以缓存机制受到了挑战。。。每次更新数组意味着缓存失效,这样一更新一查找的话相当于每次都重新计算了。

    所以要设计一个更好的缓存机制,尽量降低更新带来的影响。

    我选择分段缓存,就是把原数组的缓存分别放在多段缓存里,这样数组变动的时候只用更新一段缓存。

    我选择分成log(n) 个段,并没有什么道理。

    这样在查询rangeSum 的时候就复杂了,如果范围在同一个缓存段内就很好,当跨越缓存段的时候,要分别处理两头的两个段,然后还别忘了中间被跨越的那些段。

    因为比较菜,实现得非常繁琐。但是终归accpeted 了

    /**
     * @constructor
     * @param {number[]} nums
     */
    var NumArray = function(nums) {
        this.nums = nums;
        this.cache = [];
    
        var cacheSize = 0;
        var numsLen = nums.length;
        while (numsLen > 0) {
            cacheSize++;
            numsLen = numsLen >> 1;
        }
        
        this.cacheSize = cacheSize;
        this.segSize = Math.floor(nums.length / cacheSize);
    
        var idx = 0;
        for (var i = 0; i < cacheSize; i++) {
            var cacheStart = idx;
            var segSize = this.segSize;
            if (i === cacheSize - 1) {
                segSize = Math.max(Math.floor(nums.length / cacheSize), nums.length - idx);
            }
            var cacheEnd = idx + segSize - 1;
    
            var thatCache = [];
            var thatAcc = 0;
            for (var j = cacheStart; j <= cacheEnd; j++) {
                thatAcc += this.nums[j];
                thatCache.push(thatAcc);
            }
            this.cache.push(thatCache);
            idx = cacheEnd + 1;
        }
    };
    
    /**
     * @param {number} i
     * @param {number} val
     * @return {void}
     */
    NumArray.prototype.update = function(i, val) {
        var residual = val - this.nums[i];
        var cachePos = Math.min(Math.floor(i / this.segSize), this.cacheSize);
        this.nums[i] = val;
        var cache = this.cache[cachePos];
        var idx = i - cachePos * this.segSize;
        for (var j = idx; j < cache.length; j++) {
            cache[j] += residual;
        }
    };
    
    /**
     * @param {number} i
     * @param {number} j
     * @return {number}
     */
    NumArray.prototype.sumRange = function(i, j) {
        if (this.cache.length === 0) return 0;
        var cachePosi = Math.min(Math.floor(i / this.segSize), this.cacheSize - 1);
        var cachePosj = Math.min(Math.floor(j / this.segSize), this.cacheSize - 1);
        if (cachePosi === cachePosj) {
            var cache = this.cache[cachePosi];
            var local_i = i - cachePosi * this.segSize;
            var local_j = j - cachePosi * this.segSize;
            return cache[local_j] - cache[local_i] + this.nums[i];
        } else {
            var cache_i = this.cache[cachePosi];
            var cache_j = this.cache[cachePosj];
    
            var local_i = i - cachePosi * this.segSize;
            var local_j = j - cachePosj * this.segSize;
    
            var ret_i = cache_i[cache_i.length - 1] - cache_i[local_i] + this.nums[i];
            var ret_j = cache_j[local_j];
    
            var ret = 0;
            for (var k = cachePosi + 1; k < cachePosj; k++) {
                ret += this.cache[k][this.cache[k].length - 1];
            }
            return ret + ret_i + ret_j;
        }
    };
  • 相关阅读:
    接收xml请求流并解析字符串的例子
    通过style来控制隔行显示不同颜色 .
    显示有模式的有页面的弹出窗口 .
    WSDL生成服务端JAVA代码.bat
    web上下文监听器ServletContextListener 例子 .
    使用监听器:定时清除map缓存的key value .
    Timer和TimerTask类 例子 .
    常用的正则表达式
    算法找出数组中出现次数超过一半的数
    C++讨厌的临时变量什么时候产生
  • 原文地址:https://www.cnblogs.com/agentgamer/p/6241302.html
Copyright © 2011-2022 走看看