Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Commit 5236a57

Browse files
committed
307 更快的解法
1 parent 9efccdc commit 5236a57

File tree

2 files changed

+87
-34
lines changed

2 files changed

+87
-34
lines changed

Algorithms/0307.range-sum-query-mutable/range-sum-query-mutable.go

+67-14
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,80 @@
11
package problem0307
22

3-
// NumArray 是 nums 的和的切片
3+
// https://leetcode.com/problems/range-sum-query-mutable/discuss/75724/17-ms-Java-solution-with-segment-tree
4+
type SegmentTreeNode struct {
5+
start, end, sum int
6+
left, right *SegmentTreeNode
7+
}
8+
9+
func (node *SegmentTreeNode) update(i, val int) {
10+
if node.start == node.end {
11+
node.sum = val
12+
return
13+
}
14+
15+
mid := node.start + (node.end-node.start)/2
16+
if mid >= i {
17+
node.left.update(i, val)
18+
} else {
19+
node.right.update(i, val)
20+
}
21+
22+
node.sum = node.left.sum + node.right.sum
23+
}
24+
25+
func (node *SegmentTreeNode) sumRange(i int, j int) int {
26+
if node.start == i && node.end == j {
27+
return node.sum
28+
}
29+
30+
mid := node.start + (node.end-node.start)/2
31+
if mid >= j {
32+
return node.left.sumRange(i, j)
33+
} else if mid < i {
34+
return node.right.sumRange(i, j)
35+
} else {
36+
return node.left.sumRange(i, mid) + node.right.sumRange(mid+1, j)
37+
}
38+
}
39+
40+
func buildTree(nums []int, start, end int) *SegmentTreeNode {
41+
if start > end {
42+
return nil
43+
}
44+
45+
node := &SegmentTreeNode{
46+
start: start,
47+
end: end,
48+
}
49+
50+
if start == end {
51+
node.sum = nums[start]
52+
} else {
53+
mid := start + (end-start)/2
54+
node.left = buildTree(nums, start, mid)
55+
node.right = buildTree(nums, mid+1, end)
56+
node.sum = node.left.sum + node.right.sum
57+
}
58+
59+
return node
60+
}
61+
462
type NumArray struct {
5-
nums []int
63+
root *SegmentTreeNode
664
}
765

8-
// Constructor 返回 NumArray
966
func Constructor(nums []int) NumArray {
10-
return NumArray{nums: nums}
67+
return NumArray{
68+
buildTree(nums, 0, len(nums)-1),
69+
}
1170
}
1271

13-
// Update 更新 nums
14-
func (na *NumArray) Update(i int, v int) {
15-
na.nums[i] = v
72+
func (this *NumArray) Update(i int, val int) {
73+
this.root.update(i, val)
1674
}
1775

18-
// SumRange 返回 sum(nums[i:j+1])
19-
func (na *NumArray) SumRange(i int, j int) int {
20-
res := 0
21-
for k := i; k <= j; k++ {
22-
res += na.nums[k]
23-
}
24-
return res
76+
func (this *NumArray) SumRange(i int, j int) int {
77+
return this.root.sumRange(i, j)
2578
}
2679

2780
/**

Algorithms/0307.range-sum-query-mutable/range-sum-query-mutable_test.go

+20-20
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,30 @@ import (
66
"github.com/stretchr/testify/assert"
77
)
88

9-
func Test_SumRange(t *testing.T) {
10-
ast := assert.New(t)
11-
12-
nums := []int{1, 3, 5}
13-
14-
na := Constructor(nums)
15-
16-
ast.Equal(9, na.SumRange(0, 2), "update 前,SumRange(0, 2)")
17-
18-
na.Update(1, 2)
9+
var nums = []int{1, 3, 5}
10+
var numsnil = []int{}
1911

20-
ast.Equal(8, na.SumRange(0, 2), "update 后,SumRange(0, 2)")
21-
}
22-
23-
func Test_SumRange_2(t *testing.T) {
12+
func Test_NumArray(t *testing.T) {
2413
ast := assert.New(t)
14+
numArray := Constructor(nums)
2515

26-
nums := []int{-1}
16+
ast.Equal(9, numArray.SumRange(0, 2))
17+
numArray.Update(1, 2)
18+
ast.Equal(8, numArray.SumRange(0, 2))
19+
ast.Equal(7, numArray.SumRange(1, 2))
20+
ast.Equal(1, numArray.SumRange(0, 0))
2721

28-
na := Constructor(nums)
22+
numArray1 := Constructor(numsnil)
23+
ast.Nil(numArray1.root)
2924

30-
ast.Equal(-1, na.SumRange(0, 0), "update 前,SumRange(0, 0)")
31-
32-
na.Update(0, 1)
25+
}
3326

34-
ast.Equal(1, na.SumRange(0, 0), "update 后,SumRange(0, 2)")
27+
func Benchmark_NumArray(b *testing.B) {
28+
for i := 0; i < b.N; i++ {
29+
numArray := Constructor(nums)
30+
numArray.SumRange(0, 2)
31+
numArray.Update(1, 2)
32+
numArray.SumRange(0, 2)
33+
numArray.SumRange(1, 2)
34+
}
3535
}

0 commit comments

Comments
 (0)