2021-12-24数组链表day1
题1:
给定一个整数数组 nums
,求出数组从索引 i
到 j
(i ≤ j
)范围内元素的总和,包含 i
、j
两点。
实现 NumArray
类:
NumArray(int[] nums)
使用数组nums
初始化对象int sumRange(int i, int j)
返回数组nums
从索引i
到j
(i ≤ j
)范围内元素的总和,包含i
、j
两点(也就是sum(nums[i], nums[i + 1], ... , nums[j])
)
示例:
输入: ["NumArray", "sumRange", "sumRange", "sumRange"] [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]] 输出: [null, 1, -1, -3] 解释: NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]); numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3) numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1))
提示:
0 <= nums.length <= 104
-105 <= nums[i] <= 105
0 <= i <= j < nums.length
- 最多调用
104
次sumRange
方法
1 class NumArray { 2 int[] sum; 3 public NumArray(int[] nums) { 4 int s=0; 5 sum=new int[nums.length]; 6 for (int i=0;i<nums.length;i++){ 7 s+=nums[i]; 8 sum[i]=s; 9 } 10 } 11 12 public int sumRange(int left, int right) { 13 if (left==0) return sum[right]; 14 else return sum[right]-sum[left-1]; 15 } 16 } 17 18 /** 19 * Your NumArray object will be instantiated and called as such: 20 * NumArray obj = new NumArray(nums); 21 * int param_1 = obj.sumRange(left,right); 22 */
前缀和思想。
题2:
给定一个二维矩阵 matrix
,以下类型的多个请求:
- 计算其子矩形范围内元素的总和,该子矩阵的 左上角 为
(row1, col1)
,右下角 为(row2, col2)
。
实现 NumMatrix
类:
NumMatrix(int[][] matrix)
给定整数矩阵matrix
进行初始化int sumRegion(int row1, int col1, int row2, int col2)
返回 左上角(row1, col1)
、右下角(row2, col2)
所描述的子矩阵的元素 总和 。
示例 1:
输入: ["NumMatrix","sumRegion","sumRegion","sumRegion"] [[[[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]],[2,1,4,3],[1,1,2,2],[1,2,2,4]] 输出: [null, 8, 11, 12] 解释: NumMatrix numMatrix = new NumMatrix([[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]); numMatrix.sumRegion(2, 1, 4, 3); // return 8 (红色矩形框的元素总和) numMatrix.sumRegion(1, 1, 2, 2); // return 11 (绿色矩形框的元素总和) numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 200
-105 <= matrix[i][j] <= 105
0 <= row1 <= row2 < m
0 <= col1 <= col2 < n
- 最多调用
104
次sumRegion
方法
同理,利用前缀和的思想求出 每个角点的和,再利用减法求每一块的sum
1 class NumMatrix { 2 int[][] sum; 3 public NumMatrix(int[][] matrix) { 4 int m=matrix.length,n=matrix[0].length; 5 sum=new int[m+1][n+1]; 6 // 避免边界讨论 7 for(int i=1;i<m+1;i++){ 8 int s=0; 9 //计算该行的和 10 for(int j=1;j<n+1;j++){ 11 s+=matrix[i-1][j-1]; 12 //i ,j对应的和等于上一层的和加上这一层累计的和 13 sum[i][j]=s+sum[i-1][j]; 14 //System.out.print(sum[i][j]+" "); 15 } 16 } 17 } 18 19 public int sumRegion(int row1, int col1, int row2, int col2) { 20 return sum[row2+1][col2+1]-sum[row2+1][col1]-sum[row1][col2+1]+sum[row1][col1]; 21 } 22 23 } 24 25 /** 26 * Your NumMatrix object will be instantiated and called as such: 27 * NumMatrix obj = new NumMatrix(matrix); 28 * int param_1 = obj.sumRegion(row1,col1,row2,col2); 29 */
题目3:
给你一个整数数组 nums
和一个整数 k
,请你统计并返回该数组中和为 k
的连续子数组的个数。
示例 1:
输入:nums = [1,1,1], k = 2 输出:2
示例 2:
输入:nums = [1,2,3], k = 3 输出:2
提示:
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
前缀和思路,感觉要超时,刚好过
1 class Solution { 2 public int subarraySum(int[] nums, int k) { 3 int n=nums.length; 4 int[] presum=new int[n+1]; 5 for (int i=1;i<n+1;i++){ 6 presum[i]=presum[i-1]+nums[i-1]; 7 } 8 int res=0; 9 for(int i=1;i<n+1;i++){ 10 for(int j=1;j<=i;j++){ 11 if (presum[i]-presum[j-1]==k){ 12 res++; 13 } 14 } 15 } 16 return res; 17 } 18 }
哈希表优化
1 class Solution { 2 public int subarraySum(int[] nums, int k) { 3 int n=nums.length,sum=0; 4 int res=0; 5 Map<Integer,Integer> map=new HashMap<>(); 6 map.put(0,1); 7 for (int i=0;i<n;i++){ 8 sum+=nums[i]; 9 if (map.containsKey(sum-k)){ 10 res+=map.get(sum-k); 11 } 12 map.put(sum,map.getOrDefault(sum,0)+1); 13 } 14 return res; 15 } 16 }