1.303 区域和检索-数组不可变
问题:给定一个整数数组 nums,处理以下类型的多个查询:计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= right
实现 NumArray 类:
- NumArray(int[] nums) 使用数组 nums 初始化对象
- int sumRange(int i, int j) 返回数组 nums 中索引 left 和 right 之间的元素的 总和 ,包含 left 和 right 两点(也就是 nums[left] + nums[left + 1] + ... + nums[right] )
解答:若每次改变left和right,则都要从left到right进行for循环求和,时间复杂度为O(N)。
优化为:先利用构造函数,一次求出所有下标位置前所有元素的和,现要求下标为left到right的元素的和,则用第right位置前所有元素的和减去第(left-1)位置前所有元素的和,时间复杂度为O(1)。
2.304 二维区域和检索-矩阵不可变
问题:给定一个二维矩阵 matrix,以下类型的多个请求:计算其子矩形范围内元素的总和,该子矩阵的 左上角 为 (row1, col1) ,右下角 为 (row2, col2) 。
实现 NumMatrix 类:
- NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进行初始化
- int sumRegion(int row1, int col1, int row2, int col2) 返回 左上角 (row1, col1) 、右下角 (row2, col2) 所描述的子矩阵的元素 总和 。
解答:学习了前缀和思想,可能会想把二维数组转化为一个个的一维数组,求每一行指定位置区间的元素的和,但这时的时间复杂度:初始化 O(mn),每次检索 O(m),其中 m和 n分别是矩阵的行数和列数。
优化为:先利用构造函数,一次求出所有下标位置与原点组成的矩阵内所有元素的和(通过前边行的所有元素求和+前边列的所有元素求和-公共部分+当前位置的元素,这些值都可以求出),再由四个矩阵进行运算【当前下标位置与原点组成的矩阵内所有元素的和-(当前下标位置-1)行的位置与原点组成的矩阵所有元素的和-(当前下标位置-1)列的位置与原点组成的矩阵所有元素的和+(当前下标位置-1)行与(当前下标位置-1)列组成的矩阵内所有元素的和】,求出指定两个位置组成的矩阵内所有元素的和。时间复杂度为:初始化 O(mn),每次检索 O(1),空间复杂度:O(mn)。
3.560 和为k的子数组
问题:给你一个整数数组 nums
和一个整数 k
,请你统计并返回该数组中和为 k
的连续子数组的个数 。
解答:学习了前缀和思想,可能会想求出任意位置前元素的和,再求任意两个位置之间元素的和,若为k则+1,但这时的时间复杂度为O()。
优化为:以i结尾的和为 k的连续子数组个数时只要统计有多少个前缀和为pre[i]−k 的pre[j] 即可,建立哈希表mp,以和为键,出现次数为对应的值,记录pre[i]出现的次数,那么以 i结尾的答案mp[pre[i]−k] 即可在O(1)时间内得到。时间复杂度为O(n),空间复杂度:O(n)。