44
44
45
45
<!-- 这里可写通用的实现逻辑 -->
46
46
47
- 离散化。
47
+ 树状数组。
48
+
49
+ 树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
50
+
51
+ 1 . ** 单点更新** ` update(x, delta) ` : 把序列 x 位置的数加上一个值 delta;
52
+ 1 . ** 前缀和查询** ` query(x) ` :查询序列 ` [1,...x] ` 区间的区间和,即位置 x 的前缀和。
53
+
54
+ 这两个操作的时间复杂度均为 ` O(log n) ` 。
55
+
56
+ 本题中,对于每个下标 j,以 j 为右端点的下标对的数量,就等于 ` preSum[1..j] ` 中的所有整数,出现在区间 ` [preSum[j] - upper, preSum[j] - lower] ` 的次数。我们可以用树状数组,从左到右扫描前缀和数组,每遇到一个前缀和 s,就在树状数组中查询区间 ` [preSum[j] - upper, preSum[j] - lower] ` 内的整数的数量,随后将 s 更新至树状数组。
48
57
49
58
<!-- tabs:start -->
50
59
53
62
<!-- 这里可写当前语言的特殊实现逻辑 -->
54
63
55
64
``` python
56
- class Solution :
57
- def arrayRankTransform (self , arr : List[int ]) -> List[int ]:
58
- def find (x ):
59
- left, right = 0 , len (t) - 1
60
- while left < right:
61
- mid = (left + right) >> 1
62
- if t[mid] >= x:
63
- right = mid
64
- else :
65
- left = mid + 1
66
- return left + 1
67
-
68
- t = sorted (set (arr))
69
- return [find(x) for x in arr]
70
- ```
65
+ class BinaryIndexedTree :
66
+ def __init__ (self , n ):
67
+ self .n = n
68
+ self .c = [0 ] * (n + 1 )
69
+
70
+ @ staticmethod
71
+ def lowbit (x ):
72
+ return x & - x
73
+
74
+ def update (self , x , delta ):
75
+ while x <= self .n:
76
+ self .c[x] += delta
77
+ x += BinaryIndexedTree.lowbit(x)
78
+
79
+ def query (self , x ):
80
+ s = 0
81
+ while x > 0 :
82
+ s += self .c[x]
83
+ x -= BinaryIndexedTree.lowbit(x)
84
+ return s
85
+
71
86
72
- ``` python
73
87
class Solution :
74
- def arrayRankTransform (self , arr : List[int ]) -> List[int ]:
75
- m = {v: i for i, v in enumerate (sorted (set (arr)), 1 )}
76
- return [m[v] for v in arr]
88
+ def countRangeSum (self , nums : List[int ], lower : int , upper : int ) -> int :
89
+ presum = [0 ]
90
+ for v in nums:
91
+ presum.append(presum[- 1 ] + v)
92
+ alls = set ()
93
+ for s in presum:
94
+ alls.add(s)
95
+ alls.add(s - lower)
96
+ alls.add(s - upper)
97
+ alls = sorted (alls)
98
+ m = {v: i for i, v in enumerate (alls, 1 )}
99
+ tree = BinaryIndexedTree(len (m))
100
+ ans = 0
101
+ for s in presum:
102
+ i, j = m[s - upper], m[s - lower]
103
+ ans += tree.query(j) - tree.query(i - 1 )
104
+ tree.update(m[s], 1 )
105
+ return ans
77
106
```
78
107
79
108
### ** Java**
@@ -82,39 +111,123 @@ class Solution:
82
111
83
112
``` java
84
113
class Solution {
85
- public int [] arrayRankTransform (int [] arr ) {
86
- Set<Integer > s = new HashSet<> ();
87
- for (int v : arr) {
88
- s. add(v);
114
+ public int countRangeSum (int [] nums , int lower , int upper ) {
115
+ int n = nums. length;
116
+ long [] preSum = new long [n + 1 ];
117
+ for (int i = 0 ; i < n; ++ i) {
118
+ preSum[i + 1 ] = preSum[i] + nums[i];
119
+ }
120
+ TreeSet<Long > ts = new TreeSet<> ();
121
+ for (long s : preSum) {
122
+ ts. add(s);
123
+ ts. add(s - upper);
124
+ ts. add(s - lower);
89
125
}
90
- List<Integer > alls = new ArrayList<> (s);
91
- alls. sort((a, b) - > a - b);
92
- Map<Integer , Integer > m = new HashMap<> ();
93
- for (int i = 0 ; i < alls. size(); ++ i) {
94
- m. put(alls. get(i), i + 1 );
126
+ Map<Long , Integer > m = new HashMap<> ();
127
+ int idx = 1 ;
128
+ for (long s : ts) {
129
+ m. put(s, idx++ );
95
130
}
96
- int [] ans = new int [arr. length];
97
- for (int i = 0 ; i < arr. length; ++ i) {
98
- ans[i] = m. get(arr[i]);
131
+ int ans = 0 ;
132
+ BinaryIndexedTree tree = new BinaryIndexedTree (m. size());
133
+ for (long s : preSum) {
134
+ int i = m. get(s - upper);
135
+ int j = m. get(s - lower);
136
+ ans += tree. query(j) - tree. query(i - 1 );
137
+ tree. update(m. get(s), 1 );
99
138
}
100
139
return ans;
101
140
}
102
141
}
142
+
143
+ class BinaryIndexedTree {
144
+ private int n;
145
+ private int [] c;
146
+
147
+ public BinaryIndexedTree (int n ) {
148
+ this . n = n;
149
+ c = new int [n + 1 ];
150
+ }
151
+
152
+ public void update (int x , int delta ) {
153
+ while (x <= n) {
154
+ c[x] += delta;
155
+ x += lowbit(x);
156
+ }
157
+ }
158
+
159
+ public int query (int x ) {
160
+ int s = 0 ;
161
+ while (x > 0 ) {
162
+ s += c[x];
163
+ x -= lowbit(x);
164
+ }
165
+ return s;
166
+ }
167
+
168
+ public static int lowbit (int x ) {
169
+ return x & - x;
170
+ }
171
+ }
103
172
```
104
173
105
174
### ** C++**
106
175
107
176
``` cpp
177
+ class BinaryIndexedTree {
178
+ public:
179
+ int n;
180
+ vector<int > c;
181
+
182
+ BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
183
+
184
+ void update (int x, int delta) {
185
+ while (x <= n)
186
+ {
187
+ c[ x] += delta;
188
+ x += lowbit(x);
189
+ }
190
+ }
191
+
192
+ int query(int x) {
193
+ int s = 0;
194
+ while (x > 0)
195
+ {
196
+ s += c[x];
197
+ x -= lowbit(x);
198
+ }
199
+ return s;
200
+ }
201
+
202
+ int lowbit(int x) {
203
+ return x & -x;
204
+ }
205
+ };
206
+
108
207
class Solution {
109
208
public:
110
- vector<int > arrayRankTransform(vector<int >& arr) {
111
- unordered_set<int > s(arr.begin(), arr.end());
112
- vector<int > alls(s.begin(), s.end());
113
- sort(alls.begin(), alls.end());
114
- unordered_map<int, int> m;
115
- for (int i = 0; i < alls.size(); ++i) m[ alls[ i]] = i + 1;
116
- vector<int > ans;
117
- for (int v : arr) ans.push_back(m[ v] );
209
+ int countRangeSum(vector<int >& nums, int lower, int upper) {
210
+ int n = nums.size();
211
+ vector<long long > preSum(n + 1);
212
+ for (int i = 0; i < n; ++i) preSum[ i + 1] = preSum[ i] + nums[ i] ;
213
+ set<long long > alls;
214
+ for (auto& s : preSum)
215
+ {
216
+ alls.insert(s);
217
+ alls.insert(s - upper);
218
+ alls.insert(s - lower);
219
+ }
220
+ unordered_map<long long, int> m;
221
+ int idx = 1;
222
+ for (auto& v : alls) m[ v] = idx++;
223
+ BinaryIndexedTree* tree = new BinaryIndexedTree(m.size());
224
+ int ans = 0;
225
+ for (auto& s : preSum)
226
+ {
227
+ int i = m[ s - upper] , j = m[ s - lower] ;
228
+ ans += tree->query(j) - tree->query(i - 1);
229
+ tree->update(m[ s] , 1);
230
+ }
118
231
return ans;
119
232
}
120
233
};
@@ -123,23 +236,63 @@ public:
123
236
### **Go**
124
237
125
238
```go
126
- func arrayRankTransform(arr []int) []int {
127
- s := make(map[int]bool)
128
- for _, v := range arr {
129
- s[v] = true
239
+ type BinaryIndexedTree struct {
240
+ n int
241
+ c []int
242
+ }
243
+
244
+ func newBinaryIndexedTree(n int) *BinaryIndexedTree {
245
+ c := make([]int, n+1)
246
+ return &BinaryIndexedTree{n, c}
247
+ }
248
+
249
+ func (this *BinaryIndexedTree) lowbit(x int) int {
250
+ return x & -x
251
+ }
252
+
253
+ func (this *BinaryIndexedTree) update(x, delta int) {
254
+ for x <= this.n {
255
+ this.c[x] += delta
256
+ x += this.lowbit(x)
257
+ }
258
+ }
259
+
260
+ func (this *BinaryIndexedTree) query(x int) int {
261
+ s := 0
262
+ for x > 0 {
263
+ s += this.c[x]
264
+ x -= this.lowbit(x)
265
+ }
266
+ return s
267
+ }
268
+
269
+ func countRangeSum(nums []int, lower int, upper int) int {
270
+ n := len(nums)
271
+ presum := make([]int, n+1)
272
+ for i, v := range nums {
273
+ presum[i+1] = presum[i] + v
274
+ }
275
+ alls := make(map[int]bool)
276
+ for _, s := range presum {
277
+ alls[s] = true
278
+ alls[s-upper] = true
279
+ alls[s-lower] = true
130
280
}
131
- var alls []int
132
- for v := range s {
133
- alls = append(alls, v )
281
+ var t []int
282
+ for s, _ := range alls {
283
+ t = append(t, s )
134
284
}
135
- sort.Ints(alls )
285
+ sort.Ints(t )
136
286
m := make(map[int]int)
137
- for i, v := range alls {
287
+ for i, v := range t {
138
288
m[v] = i + 1
139
289
}
140
- var ans []int
141
- for _, v := range arr {
142
- ans = append(ans, m[v])
290
+ ans := 0
291
+ tree := newBinaryIndexedTree(len(alls))
292
+ for _, s := range presum {
293
+ i, j := m[s-upper], m[s-lower]
294
+ ans += tree.query(j) - tree.query(i-1)
295
+ tree.update(m[s], 1)
143
296
}
144
297
return ans
145
298
}
0 commit comments