LeetCode 307 Range Sum Query - Mutable(范围和查询-可变)

简介: 版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/51782135 翻译给定一个整型数组nums,找出在索引i到j之间的元素的和(i 9 update(1, 2) sumRange(0, 2) -> 8备注: 该数组只能被update函数修改。
版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/51782135

翻译

给定一个整型数组nums,找出在索引i到j之间的元素的和(i <= j),包括i 和 j。

函数update(i, val)用于修改在索引i的元素为val。

例如,
给定nums = [1, 3, 5]

sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8

备注:
该数组只能被update函数修改。
你可以假设update和sumRange函数的调用是均匀分布的。

原文

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

The update(i, val) function modifies nums by updating the element at index i to val.
Example:
Given nums = [1, 3, 5]

sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
Note:
The array is only modifiable by the update function.
You may assume the number of calls to update and sumRange function is distributed evenly.

分析

原始方法

记得之前也做过类似这么一道题,不过最简单的那种for循环并不能解决问题。那个题目最后会给很大的数据量,要用哈希表进行分区段的数据保存。所以我也以为这道题会是这样,但我用for循环居然也通过了,所以就懒得再写了。

class NumArray {
private:
    vector<int> numsV;
public:
    NumArray(vector<int> &nums) {
        numsV = nums;
    }

    void update(int i, int val) {
        numsV[i] = val;
    }

    int sumRange(int i,int j) {
        int sum = 0;
        for (int k = i; k <= j; k++) {
            sum += numsV[k];
        }
        return sum;
    }
};

开方分解

除了上面所说的用哈希表外,还可以用题中给出的开方分解的方式。

这个思想如下图所示,数组中共有9个元素,我们可以开方得到3,并以此分成3块。当我们需要求RSQ(1,7)时,那就是b[1]和值,加上前面和后面的快的部分值。

这里写图片描述

class NumArray {
private:
    int len;
    vector<int> numsV;
    vector<int> b;
public:
    NumArray(vector<int> &nums) {
        numsV = nums;
        if (nums.size() == 0)
            len = 0;
        else {
            double l = sqrt(nums.size());
            len = (int) ceil(nums.size() / l);
            b = vector<int>(len);
            for (int i = 0; i < numsV.size(); i++) {
                b[i / len] += numsV[i];
            }
        }
    }

    void update(int i, int val) {
        int b_l = i / len;
        b[b_l] = b[b_l] - numsV[i] + val;
        numsV[i] = val;
    }

    int sumRange(int i,int j) {
        if (len == 0)
            return 0;
        int sum = 0;
        int startBlock = i / len;
        int endBlock = j / len;
        if (startBlock == endBlock) {
            for (int k = i; k <= j; k++) {
                sum += numsV[k];
            }
        } else {
            for (int k = i; k <= (startBlock + 1) * len - 1; k++)
                sum += numsV[k];
            for (int k = startBlock + 1; k <= endBlock - 1; k++)
                sum += b[k];
            for (int k = endBlock * len; k <= j; k++)
                sum += numsV[k];
        }
        return sum;
    }
};
  • 时间复杂度
    • 初始化阶段为 O(n) ,update阶段为 O(1) ,sumRange阶段为 O(n)
    • 对于范围和查询来说,我们必须计算大约 3n 个元素。在这种情况下的范围包括 n2 个块,也意味着需要 n2 次操作。除此之外,还需要计算边界的两个块的元素,这需要另外 2n1 次操作。综合来看,共需要的操作大概是 3n 次。
  • 空间复杂度
    • O(n)
    • 我们需要额外的 n 快存储区域来保存所有快(block)的和

代码

哎,记得之前也做过类似这么一道题,不过最简单的那种for循环并不能解决问题。原文题目最后会给很大的数据量,要求用哈希表进行分区段的数据保存。所以我也以为这道题会是这样,但我用for循环居然也通过了,所以就懒得再写了。

目录
相关文章
|
6月前
|
SQL
leetcode-SQL-1211. 查询结果的质量和占比
leetcode-SQL-1211. 查询结果的质量和占比
32 0
|
6月前
|
SQL
leetcode-SQL-1141. 查询近30天活跃用户数
leetcode-SQL-1141. 查询近30天活跃用户数
60 0
|
6月前
|
算法 测试技术 C++
map|二分查找|离线查询|LeetCode:2736最大和查询
map|二分查找|离线查询|LeetCode:2736最大和查询
map|二分查找|离线查询|LeetCode:2736最大和查询
|
6月前
|
算法 测试技术 C#
map|二分查找|离线查询|LeetCode:2736最大和查询
map|二分查找|离线查询|LeetCode:2736最大和查询
LeetCode 307. Range Sum Query - Mutable
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
104 0
LeetCode 307. Range Sum Query - Mutable
LeetCode 304. Range Sum Query 2D - Immutable
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2)。
104 0
LeetCode 304. Range Sum Query 2D - Immutable
|
索引
LeetCode 303. Range Sum Query - Immutable
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
93 0
LeetCode 303. Range Sum Query - Immutable
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
55 6
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
113 2