Skip to content

Commit d24325a

Browse files
authored
feat: add solutions to lc problem: No.2080 (#4074)
No.2080.Range Frequency Queries
1 parent ccbac68 commit d24325a

File tree

6 files changed

+308
-44
lines changed

6 files changed

+308
-44
lines changed

solution/2000-2099/2080.Range Frequency Queries/README.md

+108-15
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ rangeFreqQuery.query(0, 11, 33); // 返回 2 。33 在整个子数组中出现 2
6868

6969
<!-- solution:start -->
7070

71-
### 方法一:哈希表
71+
### 方法一:哈希表 + 二分查找
7272

7373
我们用一个哈希表 $g$ 来存储每个值对应的下标数组。在构造函数中,我们遍历数组 $\textit{arr}$,将每个值对应的下标加入到哈希表中。
7474

@@ -215,20 +215,8 @@ class RangeFreqQuery {
215215
if (!idx) {
216216
return 0;
217217
}
218-
const search = (x: number): number => {
219-
let [l, r] = [0, idx.length];
220-
while (l < r) {
221-
const mid = (l + r) >> 1;
222-
if (idx[mid] >= x) {
223-
r = mid;
224-
} else {
225-
l = mid + 1;
226-
}
227-
}
228-
return l;
229-
};
230-
const l = search(left);
231-
const r = search(right + 1);
218+
const l = _.sortedIndex(idx, left);
219+
const r = _.sortedIndex(idx, right + 1);
232220
return r - l;
233221
}
234222
}
@@ -240,6 +228,111 @@ class RangeFreqQuery {
240228
*/
241229
```
242230

231+
#### Rust
232+
233+
```rust
234+
use std::collections::HashMap;
235+
236+
struct RangeFreqQuery {
237+
g: HashMap<i32, Vec<usize>>,
238+
}
239+
240+
impl RangeFreqQuery {
241+
fn new(arr: Vec<i32>) -> Self {
242+
let mut g = HashMap::new();
243+
for (i, &value) in arr.iter().enumerate() {
244+
g.entry(value).or_insert_with(Vec::new).push(i);
245+
}
246+
RangeFreqQuery { g }
247+
}
248+
249+
fn query(&self, left: i32, right: i32, value: i32) -> i32 {
250+
if let Some(idx) = self.g.get(&value) {
251+
let l = idx.partition_point(|&x| x < left as usize);
252+
let r = idx.partition_point(|&x| x <= right as usize);
253+
return (r - l) as i32;
254+
}
255+
0
256+
}
257+
}
258+
```
259+
260+
#### JavaScript
261+
262+
```js
263+
/**
264+
* @param {number[]} arr
265+
*/
266+
var RangeFreqQuery = function (arr) {
267+
this.g = new Map();
268+
269+
for (let i = 0; i < arr.length; ++i) {
270+
if (!this.g.has(arr[i])) {
271+
this.g.set(arr[i], []);
272+
}
273+
this.g.get(arr[i]).push(i);
274+
}
275+
};
276+
277+
/**
278+
* @param {number} left
279+
* @param {number} right
280+
* @param {number} value
281+
* @return {number}
282+
*/
283+
RangeFreqQuery.prototype.query = function (left, right, value) {
284+
const idx = this.g.get(value);
285+
if (!idx) {
286+
return 0;
287+
}
288+
const l = _.sortedIndex(idx, left);
289+
const r = _.sortedIndex(idx, right + 1);
290+
return r - l;
291+
};
292+
293+
/**
294+
* Your RangeFreqQuery object will be instantiated and called as such:
295+
* var obj = new RangeFreqQuery(arr)
296+
* var param_1 = obj.query(left,right,value)
297+
*/
298+
```
299+
300+
#### C#
301+
302+
```cs
303+
public class RangeFreqQuery {
304+
private Dictionary<int, List<int>> g;
305+
306+
public RangeFreqQuery(int[] arr) {
307+
g = new Dictionary<int, List<int>>();
308+
for (int i = 0; i < arr.Length; ++i) {
309+
if (!g.ContainsKey(arr[i])) {
310+
g[arr[i]] = new List<int>();
311+
}
312+
g[arr[i]].Add(i);
313+
}
314+
}
315+
316+
public int Query(int left, int right, int value) {
317+
if (g.ContainsKey(value)) {
318+
var idx = g[value];
319+
int l = idx.BinarySearch(left);
320+
int r = idx.BinarySearch(right + 1);
321+
l = l < 0 ? -l - 1 : l;
322+
r = r < 0 ? -r - 1 : r;
323+
return r - l;
324+
}
325+
return 0;
326+
}
327+
}
328+
329+
/**
330+
* Your RangeFreqQuery object will be instantiated and called as such:
331+
* RangeFreqQuery obj = new RangeFreqQuery(arr);
332+
* int param_1 = obj.Query(left, right, value);
333+
*/
334+
```
335+
243336
<!-- tabs:end -->
244337

245338
<!-- solution:end -->

solution/2000-2099/2080.Range Frequency Queries/README_EN.md

+108-15
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ rangeFreqQuery.query(0, 11, 33); // return 2. The value 33 occurs 2 times in the
6767

6868
<!-- solution:start -->
6969

70-
### Solution 1: Hash Table
70+
### Solution 1: Hash Table + Binary Search
7171

7272
We use a hash table $g$ to store the array of indices corresponding to each value. In the constructor, we traverse the array $\textit{arr}$, adding the index corresponding to each value to the hash table.
7373

@@ -214,20 +214,8 @@ class RangeFreqQuery {
214214
if (!idx) {
215215
return 0;
216216
}
217-
const search = (x: number): number => {
218-
let [l, r] = [0, idx.length];
219-
while (l < r) {
220-
const mid = (l + r) >> 1;
221-
if (idx[mid] >= x) {
222-
r = mid;
223-
} else {
224-
l = mid + 1;
225-
}
226-
}
227-
return l;
228-
};
229-
const l = search(left);
230-
const r = search(right + 1);
217+
const l = _.sortedIndex(idx, left);
218+
const r = _.sortedIndex(idx, right + 1);
231219
return r - l;
232220
}
233221
}
@@ -239,6 +227,111 @@ class RangeFreqQuery {
239227
*/
240228
```
241229

230+
#### Rust
231+
232+
```rust
233+
use std::collections::HashMap;
234+
235+
struct RangeFreqQuery {
236+
g: HashMap<i32, Vec<usize>>,
237+
}
238+
239+
impl RangeFreqQuery {
240+
fn new(arr: Vec<i32>) -> Self {
241+
let mut g = HashMap::new();
242+
for (i, &value) in arr.iter().enumerate() {
243+
g.entry(value).or_insert_with(Vec::new).push(i);
244+
}
245+
RangeFreqQuery { g }
246+
}
247+
248+
fn query(&self, left: i32, right: i32, value: i32) -> i32 {
249+
if let Some(idx) = self.g.get(&value) {
250+
let l = idx.partition_point(|&x| x < left as usize);
251+
let r = idx.partition_point(|&x| x <= right as usize);
252+
return (r - l) as i32;
253+
}
254+
0
255+
}
256+
}
257+
```
258+
259+
#### JavaScript
260+
261+
```js
262+
/**
263+
* @param {number[]} arr
264+
*/
265+
var RangeFreqQuery = function (arr) {
266+
this.g = new Map();
267+
268+
for (let i = 0; i < arr.length; ++i) {
269+
if (!this.g.has(arr[i])) {
270+
this.g.set(arr[i], []);
271+
}
272+
this.g.get(arr[i]).push(i);
273+
}
274+
};
275+
276+
/**
277+
* @param {number} left
278+
* @param {number} right
279+
* @param {number} value
280+
* @return {number}
281+
*/
282+
RangeFreqQuery.prototype.query = function (left, right, value) {
283+
const idx = this.g.get(value);
284+
if (!idx) {
285+
return 0;
286+
}
287+
const l = _.sortedIndex(idx, left);
288+
const r = _.sortedIndex(idx, right + 1);
289+
return r - l;
290+
};
291+
292+
/**
293+
* Your RangeFreqQuery object will be instantiated and called as such:
294+
* var obj = new RangeFreqQuery(arr)
295+
* var param_1 = obj.query(left,right,value)
296+
*/
297+
```
298+
299+
#### C#
300+
301+
```cs
302+
public class RangeFreqQuery {
303+
private Dictionary<int, List<int>> g;
304+
305+
public RangeFreqQuery(int[] arr) {
306+
g = new Dictionary<int, List<int>>();
307+
for (int i = 0; i < arr.Length; ++i) {
308+
if (!g.ContainsKey(arr[i])) {
309+
g[arr[i]] = new List<int>();
310+
}
311+
g[arr[i]].Add(i);
312+
}
313+
}
314+
315+
public int Query(int left, int right, int value) {
316+
if (g.ContainsKey(value)) {
317+
var idx = g[value];
318+
int l = idx.BinarySearch(left);
319+
int r = idx.BinarySearch(right + 1);
320+
l = l < 0 ? -l - 1 : l;
321+
r = r < 0 ? -r - 1 : r;
322+
return r - l;
323+
}
324+
return 0;
325+
}
326+
}
327+
328+
/**
329+
* Your RangeFreqQuery object will be instantiated and called as such:
330+
* RangeFreqQuery obj = new RangeFreqQuery(arr);
331+
* int param_1 = obj.Query(left, right, value);
332+
*/
333+
```
334+
242335
<!-- tabs:end -->
243336

244337
<!-- solution:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
public class RangeFreqQuery {
2+
private Dictionary<int, List<int>> g;
3+
4+
public RangeFreqQuery(int[] arr) {
5+
g = new Dictionary<int, List<int>>();
6+
for (int i = 0; i < arr.Length; ++i) {
7+
if (!g.ContainsKey(arr[i])) {
8+
g[arr[i]] = new List<int>();
9+
}
10+
g[arr[i]].Add(i);
11+
}
12+
}
13+
14+
public int Query(int left, int right, int value) {
15+
if (g.ContainsKey(value)) {
16+
var idx = g[value];
17+
int l = idx.BinarySearch(left);
18+
int r = idx.BinarySearch(right + 1);
19+
l = l < 0 ? -l - 1 : l;
20+
r = r < 0 ? -r - 1 : r;
21+
return r - l;
22+
}
23+
return 0;
24+
}
25+
}
26+
27+
/**
28+
* Your RangeFreqQuery object will be instantiated and called as such:
29+
* RangeFreqQuery obj = new RangeFreqQuery(arr);
30+
* int param_1 = obj.Query(left, right, value);
31+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @param {number[]} arr
3+
*/
4+
var RangeFreqQuery = function (arr) {
5+
this.g = new Map();
6+
7+
for (let i = 0; i < arr.length; ++i) {
8+
if (!this.g.has(arr[i])) {
9+
this.g.set(arr[i], []);
10+
}
11+
this.g.get(arr[i]).push(i);
12+
}
13+
};
14+
15+
/**
16+
* @param {number} left
17+
* @param {number} right
18+
* @param {number} value
19+
* @return {number}
20+
*/
21+
RangeFreqQuery.prototype.query = function (left, right, value) {
22+
const idx = this.g.get(value);
23+
if (!idx) {
24+
return 0;
25+
}
26+
const l = _.sortedIndex(idx, left);
27+
const r = _.sortedIndex(idx, right + 1);
28+
return r - l;
29+
};
30+
31+
/**
32+
* Your RangeFreqQuery object will be instantiated and called as such:
33+
* var obj = new RangeFreqQuery(arr)
34+
* var param_1 = obj.query(left,right,value)
35+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use std::collections::HashMap;
2+
3+
struct RangeFreqQuery {
4+
g: HashMap<i32, Vec<usize>>,
5+
}
6+
7+
impl RangeFreqQuery {
8+
fn new(arr: Vec<i32>) -> Self {
9+
let mut g = HashMap::new();
10+
for (i, &value) in arr.iter().enumerate() {
11+
g.entry(value).or_insert_with(Vec::new).push(i);
12+
}
13+
RangeFreqQuery { g }
14+
}
15+
16+
fn query(&self, left: i32, right: i32, value: i32) -> i32 {
17+
if let Some(idx) = self.g.get(&value) {
18+
let l = idx.partition_point(|&x| x < left as usize);
19+
let r = idx.partition_point(|&x| x <= right as usize);
20+
return (r - l) as i32;
21+
}
22+
0
23+
}
24+
}

0 commit comments

Comments
 (0)