From 1420a99c5c14eca7a779fca317d212db2d912c59 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 18 Feb 2025 08:59:02 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.2080 No.2080.Range Frequency Queries --- .../2080.Range Frequency Queries/README.md | 123 +++++++++++++++--- .../2080.Range Frequency Queries/README_EN.md | 123 +++++++++++++++--- .../2080.Range Frequency Queries/Solution.cs | 31 +++++ .../2080.Range Frequency Queries/Solution.js | 35 +++++ .../2080.Range Frequency Queries/Solution.rs | 24 ++++ .../2080.Range Frequency Queries/Solution.ts | 16 +-- 6 files changed, 308 insertions(+), 44 deletions(-) create mode 100644 solution/2000-2099/2080.Range Frequency Queries/Solution.cs create mode 100644 solution/2000-2099/2080.Range Frequency Queries/Solution.js create mode 100644 solution/2000-2099/2080.Range Frequency Queries/Solution.rs diff --git a/solution/2000-2099/2080.Range Frequency Queries/README.md b/solution/2000-2099/2080.Range Frequency Queries/README.md index 3e5f7b21a2f5c..4e064fa154100 100644 --- a/solution/2000-2099/2080.Range Frequency Queries/README.md +++ b/solution/2000-2099/2080.Range Frequency Queries/README.md @@ -68,7 +68,7 @@ rangeFreqQuery.query(0, 11, 33); // 返回 2 。33 在整个子数组中出现 2 -### 方法一:哈希表 +### 方法一:哈希表 + 二分查找 我们用一个哈希表 $g$ 来存储每个值对应的下标数组。在构造函数中,我们遍历数组 $\textit{arr}$,将每个值对应的下标加入到哈希表中。 @@ -215,20 +215,8 @@ class RangeFreqQuery { if (!idx) { return 0; } - const search = (x: number): number => { - let [l, r] = [0, idx.length]; - while (l < r) { - const mid = (l + r) >> 1; - if (idx[mid] >= x) { - r = mid; - } else { - l = mid + 1; - } - } - return l; - }; - const l = search(left); - const r = search(right + 1); + const l = _.sortedIndex(idx, left); + const r = _.sortedIndex(idx, right + 1); return r - l; } } @@ -240,6 +228,111 @@ class RangeFreqQuery { */ ``` +#### Rust + +```rust +use std::collections::HashMap; + +struct RangeFreqQuery { + g: HashMap>, +} + +impl RangeFreqQuery { + fn new(arr: Vec) -> Self { + let mut g = HashMap::new(); + for (i, &value) in arr.iter().enumerate() { + g.entry(value).or_insert_with(Vec::new).push(i); + } + RangeFreqQuery { g } + } + + fn query(&self, left: i32, right: i32, value: i32) -> i32 { + if let Some(idx) = self.g.get(&value) { + let l = idx.partition_point(|&x| x < left as usize); + let r = idx.partition_point(|&x| x <= right as usize); + return (r - l) as i32; + } + 0 + } +} +``` + +#### JavaScript + +```js +/** + * @param {number[]} arr + */ +var RangeFreqQuery = function (arr) { + this.g = new Map(); + + for (let i = 0; i < arr.length; ++i) { + if (!this.g.has(arr[i])) { + this.g.set(arr[i], []); + } + this.g.get(arr[i]).push(i); + } +}; + +/** + * @param {number} left + * @param {number} right + * @param {number} value + * @return {number} + */ +RangeFreqQuery.prototype.query = function (left, right, value) { + const idx = this.g.get(value); + if (!idx) { + return 0; + } + const l = _.sortedIndex(idx, left); + const r = _.sortedIndex(idx, right + 1); + return r - l; +}; + +/** + * Your RangeFreqQuery object will be instantiated and called as such: + * var obj = new RangeFreqQuery(arr) + * var param_1 = obj.query(left,right,value) + */ +``` + +#### C# + +```cs +public class RangeFreqQuery { + private Dictionary> g; + + public RangeFreqQuery(int[] arr) { + g = new Dictionary>(); + for (int i = 0; i < arr.Length; ++i) { + if (!g.ContainsKey(arr[i])) { + g[arr[i]] = new List(); + } + g[arr[i]].Add(i); + } + } + + public int Query(int left, int right, int value) { + if (g.ContainsKey(value)) { + var idx = g[value]; + int l = idx.BinarySearch(left); + int r = idx.BinarySearch(right + 1); + l = l < 0 ? -l - 1 : l; + r = r < 0 ? -r - 1 : r; + return r - l; + } + return 0; + } +} + +/** + * Your RangeFreqQuery object will be instantiated and called as such: + * RangeFreqQuery obj = new RangeFreqQuery(arr); + * int param_1 = obj.Query(left, right, value); + */ +``` + diff --git a/solution/2000-2099/2080.Range Frequency Queries/README_EN.md b/solution/2000-2099/2080.Range Frequency Queries/README_EN.md index 7945cfe3ed4ee..2cd33bf0b4d26 100644 --- a/solution/2000-2099/2080.Range Frequency Queries/README_EN.md +++ b/solution/2000-2099/2080.Range Frequency Queries/README_EN.md @@ -67,7 +67,7 @@ rangeFreqQuery.query(0, 11, 33); // return 2. The value 33 occurs 2 times in the -### Solution 1: Hash Table +### Solution 1: Hash Table + Binary Search 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. @@ -214,20 +214,8 @@ class RangeFreqQuery { if (!idx) { return 0; } - const search = (x: number): number => { - let [l, r] = [0, idx.length]; - while (l < r) { - const mid = (l + r) >> 1; - if (idx[mid] >= x) { - r = mid; - } else { - l = mid + 1; - } - } - return l; - }; - const l = search(left); - const r = search(right + 1); + const l = _.sortedIndex(idx, left); + const r = _.sortedIndex(idx, right + 1); return r - l; } } @@ -239,6 +227,111 @@ class RangeFreqQuery { */ ``` +#### Rust + +```rust +use std::collections::HashMap; + +struct RangeFreqQuery { + g: HashMap>, +} + +impl RangeFreqQuery { + fn new(arr: Vec) -> Self { + let mut g = HashMap::new(); + for (i, &value) in arr.iter().enumerate() { + g.entry(value).or_insert_with(Vec::new).push(i); + } + RangeFreqQuery { g } + } + + fn query(&self, left: i32, right: i32, value: i32) -> i32 { + if let Some(idx) = self.g.get(&value) { + let l = idx.partition_point(|&x| x < left as usize); + let r = idx.partition_point(|&x| x <= right as usize); + return (r - l) as i32; + } + 0 + } +} +``` + +#### JavaScript + +```js +/** + * @param {number[]} arr + */ +var RangeFreqQuery = function (arr) { + this.g = new Map(); + + for (let i = 0; i < arr.length; ++i) { + if (!this.g.has(arr[i])) { + this.g.set(arr[i], []); + } + this.g.get(arr[i]).push(i); + } +}; + +/** + * @param {number} left + * @param {number} right + * @param {number} value + * @return {number} + */ +RangeFreqQuery.prototype.query = function (left, right, value) { + const idx = this.g.get(value); + if (!idx) { + return 0; + } + const l = _.sortedIndex(idx, left); + const r = _.sortedIndex(idx, right + 1); + return r - l; +}; + +/** + * Your RangeFreqQuery object will be instantiated and called as such: + * var obj = new RangeFreqQuery(arr) + * var param_1 = obj.query(left,right,value) + */ +``` + +#### C# + +```cs +public class RangeFreqQuery { + private Dictionary> g; + + public RangeFreqQuery(int[] arr) { + g = new Dictionary>(); + for (int i = 0; i < arr.Length; ++i) { + if (!g.ContainsKey(arr[i])) { + g[arr[i]] = new List(); + } + g[arr[i]].Add(i); + } + } + + public int Query(int left, int right, int value) { + if (g.ContainsKey(value)) { + var idx = g[value]; + int l = idx.BinarySearch(left); + int r = idx.BinarySearch(right + 1); + l = l < 0 ? -l - 1 : l; + r = r < 0 ? -r - 1 : r; + return r - l; + } + return 0; + } +} + +/** + * Your RangeFreqQuery object will be instantiated and called as such: + * RangeFreqQuery obj = new RangeFreqQuery(arr); + * int param_1 = obj.Query(left, right, value); + */ +``` + diff --git a/solution/2000-2099/2080.Range Frequency Queries/Solution.cs b/solution/2000-2099/2080.Range Frequency Queries/Solution.cs new file mode 100644 index 0000000000000..0f675a7a0c951 --- /dev/null +++ b/solution/2000-2099/2080.Range Frequency Queries/Solution.cs @@ -0,0 +1,31 @@ +public class RangeFreqQuery { + private Dictionary> g; + + public RangeFreqQuery(int[] arr) { + g = new Dictionary>(); + for (int i = 0; i < arr.Length; ++i) { + if (!g.ContainsKey(arr[i])) { + g[arr[i]] = new List(); + } + g[arr[i]].Add(i); + } + } + + public int Query(int left, int right, int value) { + if (g.ContainsKey(value)) { + var idx = g[value]; + int l = idx.BinarySearch(left); + int r = idx.BinarySearch(right + 1); + l = l < 0 ? -l - 1 : l; + r = r < 0 ? -r - 1 : r; + return r - l; + } + return 0; + } +} + +/** + * Your RangeFreqQuery object will be instantiated and called as such: + * RangeFreqQuery obj = new RangeFreqQuery(arr); + * int param_1 = obj.Query(left, right, value); + */ diff --git a/solution/2000-2099/2080.Range Frequency Queries/Solution.js b/solution/2000-2099/2080.Range Frequency Queries/Solution.js new file mode 100644 index 0000000000000..14b374d0ec9ee --- /dev/null +++ b/solution/2000-2099/2080.Range Frequency Queries/Solution.js @@ -0,0 +1,35 @@ +/** + * @param {number[]} arr + */ +var RangeFreqQuery = function (arr) { + this.g = new Map(); + + for (let i = 0; i < arr.length; ++i) { + if (!this.g.has(arr[i])) { + this.g.set(arr[i], []); + } + this.g.get(arr[i]).push(i); + } +}; + +/** + * @param {number} left + * @param {number} right + * @param {number} value + * @return {number} + */ +RangeFreqQuery.prototype.query = function (left, right, value) { + const idx = this.g.get(value); + if (!idx) { + return 0; + } + const l = _.sortedIndex(idx, left); + const r = _.sortedIndex(idx, right + 1); + return r - l; +}; + +/** + * Your RangeFreqQuery object will be instantiated and called as such: + * var obj = new RangeFreqQuery(arr) + * var param_1 = obj.query(left,right,value) + */ diff --git a/solution/2000-2099/2080.Range Frequency Queries/Solution.rs b/solution/2000-2099/2080.Range Frequency Queries/Solution.rs new file mode 100644 index 0000000000000..d9d360c422398 --- /dev/null +++ b/solution/2000-2099/2080.Range Frequency Queries/Solution.rs @@ -0,0 +1,24 @@ +use std::collections::HashMap; + +struct RangeFreqQuery { + g: HashMap>, +} + +impl RangeFreqQuery { + fn new(arr: Vec) -> Self { + let mut g = HashMap::new(); + for (i, &value) in arr.iter().enumerate() { + g.entry(value).or_insert_with(Vec::new).push(i); + } + RangeFreqQuery { g } + } + + fn query(&self, left: i32, right: i32, value: i32) -> i32 { + if let Some(idx) = self.g.get(&value) { + let l = idx.partition_point(|&x| x < left as usize); + let r = idx.partition_point(|&x| x <= right as usize); + return (r - l) as i32; + } + 0 + } +} diff --git a/solution/2000-2099/2080.Range Frequency Queries/Solution.ts b/solution/2000-2099/2080.Range Frequency Queries/Solution.ts index 2ff602ed7618b..fb92babdfb118 100644 --- a/solution/2000-2099/2080.Range Frequency Queries/Solution.ts +++ b/solution/2000-2099/2080.Range Frequency Queries/Solution.ts @@ -15,20 +15,8 @@ class RangeFreqQuery { if (!idx) { return 0; } - const search = (x: number): number => { - let [l, r] = [0, idx.length]; - while (l < r) { - const mid = (l + r) >> 1; - if (idx[mid] >= x) { - r = mid; - } else { - l = mid + 1; - } - } - return l; - }; - const l = search(left); - const r = search(right + 1); + const l = _.sortedIndex(idx, left); + const r = _.sortedIndex(idx, right + 1); return r - l; } }