Golang每日一练(leetDay0103) 区域和检索1~3

简介: Golang每日一练(leetDay0103) 区域和检索1~3

303. 区域和检索 - 数组不可变 Range Sum Query Immutable

给定一个整数数组  nums,处理以下类型的多个查询:

  1. 计算索引 leftright (包含 leftright)之间的 nums 元素的 ,其中 left <= right

实现 NumArray 类:

  • NumArray(int[] nums) 使用数组 nums 初始化对象
  • int sumRange(int i, int j) 返回数组 nums 中索引 leftright 之间的元素的 总和 ,包含 leftright 两点(也就是 nums[left] + nums[left + 1] + ... + nums[right] )

示例 1:

输入:

["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))


提示:

  • 1 <= nums.length <= 10^4
  • -10^5 <= nums[i] <= 10^5
  • 0 <= i <= j < nums.length
  • 最多调用 10^4sumRange 方法

代码:

package main
import "fmt"
type NumArray struct {
  prefixSum []int
}
func Constructor(nums []int) NumArray {
  n := len(nums)
  prefixSum := make([]int, n+1)
  for i := 0; i < n; i++ {
    prefixSum[i+1] = prefixSum[i] + nums[i]
  }
  return NumArray{prefixSum}
}
func (this *NumArray) SumRange(left int, right int) int {
  // 返回区间和
  return this.prefixSum[right+1] - this.prefixSum[left]
}
func main() {
  nums := []int{-2, 0, 3, -5, 2, -1}
  obj := Constructor(nums)
  fmt.Println(obj.SumRange(0, 2))
  fmt.Println(obj.SumRange(2, 5))
  fmt.Println(obj.SumRange(0, 5))
}

输出:

1

-1

-3


304. 二维区域和检索 - 矩阵不可变 Range Sum Query 2d Immutable

给定一个二维矩阵 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
  • -10^5 <= matrix[i][j] <= 10^5
  • 0 <= row1 <= row2 < m
  • 0 <= col1 <= col2 < n
  • 最多调用 10^4sumRegion 方法

代码:

package main
import "fmt"
type NumMatrix struct {
  prefixSum [][]int
}
func Constructor(matrix [][]int) NumMatrix {
  m, n := len(matrix), len(matrix[0])
  prefixSum := make([][]int, m+1)
  for i := range prefixSum {
    prefixSum[i] = make([]int, n+1)
  }
  for i := 1; i <= m; i++ {
    for j := 1; j <= n; j++ {
      prefixSum[i][j] = matrix[i-1][j-1] + prefixSum[i][j-1] + prefixSum[i-1][j] - prefixSum[i-1][j-1]
    }
  }
  return NumMatrix{prefixSum}
}
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
  return this.prefixSum[row2+1][col2+1] - this.prefixSum[row2+1][col1] - this.prefixSum[row1][col2+1] + this.prefixSum[row1][col1]
}
func main() {
  numMatrix := [][]int{
    {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}}
  obj := Constructor(numMatrix)
  fmt.Println(obj.SumRegion(2, 1, 4, 3))
  fmt.Println(obj.SumRegion(1, 1, 2, 2))
  fmt.Println(obj.SumRegion(1, 2, 2, 4))
}

输出:

8

11

12


307. 区域和检索 - 数组可修改 Range Sum Query Mutable

给你一个数组 nums ,请你完成两类查询。

  1. 其中一类查询要求 更新 数组 nums 下标对应的值
  2. 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 ,其中 left <= right

实现 NumArray 类:

  • NumArray(int[] nums) 用整数数组 nums 初始化对象
  • void update(int index, int val)nums[index] 的值 更新val
  • int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 (即,nums[left] + nums[left + 1], ..., nums[right]

示例 1:

输入

["NumArray", "sumRange", "update", "sumRange"]

[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]

输出

[null, 9, null, 8]


解释

NumArray numArray = new NumArray([1, 3, 5]);

numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9

numArray.update(1, 2);   // nums = [1,2,5]

numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8


提示:

  • 1 <= nums.length <= 3 * 10^4
  • -100 <= nums[i] <= 100
  • 0 <= index < nums.length
  • -100 <= val <= 100
  • 0 <= left <= right < nums.length
  • 调用 updatesumRange 方法次数不大于 3 * 10^4

代码:

package main
import "fmt"
type NumArray struct {
  tree []int
  n    int
}
func Constructor(nums []int) NumArray {
  n := len(nums)
  tree := make([]int, n*4)
  if n > 0 {
    buildTree(tree, nums, 1, 0, n-1)
  }
  return NumArray{tree, n}
}
func buildTree(tree []int, nums []int, node, start, end int) {
  if start == end {
    tree[node] = nums[start]
    return
  }
  mid := start + (end-start)/2
  leftNode, rightNode := node*2, node*2+1
  buildTree(tree, nums, leftNode, start, mid)
  buildTree(tree, nums, rightNode, mid+1, end)
  tree[node] = tree[leftNode] + tree[rightNode]
}
func (this *NumArray) Update(index int, val int) {
  updateTree(this.tree, 1, 0, this.n-1, index, val)
}
func updateTree(tree []int, node, start, end, index, val int) {
  if start == end {
    tree[node] = val
    return
  }
  mid := start + (end-start)/2
  leftNode, rightNode := node*2, node*2+1
  if index <= mid {
    updateTree(tree, leftNode, start, mid, index, val)
  } else {
    updateTree(tree, rightNode, mid+1, end, index, val)
  }
  tree[node] = tree[leftNode] + tree[rightNode]
}
func (this *NumArray) SumRange(left int, right int) int {
  return queryTree(this.tree, 1, 0, this.n-1, left, right)
}
func queryTree(tree []int, node, start, end, left, right int) int {
  if start > right || end < left {
    return 0
  }
  if start >= left && end <= right {
    return tree[node]
  }
  mid := start + (end-start)/2
  leftSum := queryTree(tree, node*2, start, mid, left, right)
  rightSum := queryTree(tree, node*2+1, mid+1, end, left, right)
  return leftSum + rightSum
}
func main() {
  numArray := []int{1, 3, 5}
  obj := Constructor(numArray)
  fmt.Println(obj.SumRange(0, 2))
  obj.Update(1, 2)
  fmt.Println(obj.SumRange(0, 2))
}

输出:

9

8


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力!

🌟 收藏,你的青睐是我努力的方向!

评论,你的意见是我进步的财富!  

主页:https://hannyang.blog.csdn.net/

Rust每日一练 专栏

(2023.5.16~)更新中...

Golang每日一练 专栏

(2023.3.11~)更新中...

Python每日一练 专栏

(2023.2.18~2023.5.18)暂停更

C/C++每日一练 专栏

(2023.2.18~2023.5.18)暂停更

Java每日一练 专栏

(2023.3.11~2023.5.18)暂停更


目录
相关文章
|
2月前
|
存储 编译器 C++
在C++语言中计算并打印出两个数的求和
在C++语言中计算并打印出两个数的求和
22 0
汉诺塔问题(递归)/梵塔问题c++
汉诺塔问题(递归)/梵塔问题c++
|
4月前
|
C语言 C++
【C++之数组与指针2】利用指针对数组求和
【C++之数组与指针2】利用指针对数组求和
|
4月前
|
Java 编译器 C++
颠倒二进制位(C++)
颠倒二进制位(C++)
34 1
|
2月前
|
设计模式 中间件 程序员
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
20 3
|
2月前
|
算法 网络协议 编译器
【C++ 14 新特性】C++14二进制字面量:深度探索与实践
【C++ 14 新特性】C++14二进制字面量:深度探索与实践
41 1
|
4月前
|
C++
二进制求和(C++)
二进制求和(C++)
38 1
|
8天前
|
C++
十进制二进制相互转化C++
十进制二进制相互转化C++
5 0
|
17天前
|
C++
C++ 递归与面向对象编程基础
C++ 递归是函数自我调用的技术,用于简化复杂问题。以递归求和为例,`sum` 函数通过不断调用自身累加数字直到 `k` 为 0。递归需谨慎,避免无限循环和资源浪费。面向对象编程(OOP)将程序划分为交互对象,具有属性和方法,提升代码复用、维护和扩展性。C++ OOP 基本概念包括类、对象、属性和方法。通过创建类和对象,利用点语法访问成员,实现代码组织。
24 0