Skip to content

Commit fde2276

Browse files
committed
Added problems: 1814 - Count Nice Pairs in an Array + Added benchmarking
1 parent e756130 commit fde2276

File tree

5 files changed

+157
-1
lines changed

5 files changed

+157
-1
lines changed

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,9 @@ version = "0.1.0"
44
license = "MIT"
55
edition = "2021"
66

7-
[dependencies]
7+
[dev-dependencies]
8+
criterion = "0.7"
9+
10+
[[bench]]
11+
name = "p1814"
12+
harness = false

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Note that this license applies only to my solution code and not to the LeetCode
5858
| 🟢 1464. [Maximum Product of Two Elements in an Array](https://leetcode.com/problems/maximum-product-of-two-elements-in-an-array/) | [🦀](src/problems/p1464_maximum_product_of_two_elements_in_an_array.rs) | |
5959
| 🟠 1599. [Maximum Profit of Operating a Centennial Wheel](https://leetcode.com/problems/maximum-profit-of-operating-a-centennial-wheel/) | [🦀](src/problems/p1599_maximum_profit_of_operating_a_centennial_wheel.rs) | |
6060
| 🟢 1784. [Check if Binary String Has at Most One Segment of Ones](https://leetcode.com/problems/check-if-binary-string-has-at-most-one-segment-of-ones/) | [🦀](src/problems/p1784_check_if_binary_string_has_at_most_one_segment_of_ones.rs) | |
61+
| 🟠 1814. [Count Nice Pairs in an Array](https://leetcode.com/problems/count-nice-pairs-in-an-array/) | [🦀](src/problems/p1814_count_nice_pairs_in_an_array.rs) | HashMap |
6162
| 🔴 1866. [Number of Ways to Rearrange Sticks With K Sticks Visible](https://leetcode.com/problems/number-of-ways-to-rearrange-sticks-with-k-sticks-visible/) | [🦀](src/problems/p1866_number_of_ways_to_rearrange_sticks_with_k_sticks_visible.rs) | Dynamic Programming |
6263
| 🟢 1876. [Substrings of Size Three with Distinct Characters](https://leetcode.com/problems/substrings-of-size-three-with-distinct-characters/) | [🦀](src/problems/p1876_substrings_of_size_three_with_distinct_characters.rs) | |
6364
| 🟢 1974. [Minimum Time to Type Word Using Special Typewriter](https://leetcode.com/problems/minimum-time-to-type-word-using-special-typewriter/) | [🦀](src/problems/p1974_minimimum_time_to_type_word_using_special_typewriter.rs) | |
@@ -139,3 +140,33 @@ pub mod pNNNN_problem_title;
139140
4. Add the problem to the [Problems](#problems) table in `README.md`
140141
5. Run the tests with `cargo test` to make sure everything is working.
141142
6. Commit your changes.
143+
144+
## Benchmarking
145+
146+
For benchmarking, the `criterion` crate is used.
147+
148+
To add a new benchmark, create a new file in the [/benches/](/benches/) directory and add a new `[[branch]]` section
149+
in [Cargo.toml](Cargo.toml).
150+
151+
To execute a benchmark, run one of the following commands:
152+
153+
```bash
154+
# Run all benchmarks
155+
cargo bench
156+
157+
# Run all benchmarks defined in a specific file
158+
cargo bench --bench p1814
159+
```
160+
161+
Also, you can run them more precisely using special syntax. E.g.:
162+
163+
```
164+
# Run only the benchmark for the specific number 1234
165+
cargo bench --bench p1814 "loop_based_1234"
166+
167+
# Run all loop-based benchmarks
168+
cargo bench --bench p1814 "loop_based_.*"
169+
```
170+
171+
See the [Criterion documentation](https://bheisler.github.io/criterion.rs/book/user_guide/known_limitations.html)
172+
for more information or run `cargo help bench`.

benches/p1814.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// benches/p1814
2+
use criterion::{criterion_group, criterion_main, Criterion};
3+
use leetcode_rust::problems::p1814_count_nice_pairs_in_an_array::Solution;
4+
use std::hint::black_box;
5+
6+
fn bench_count_nice_pairs(c: &mut Criterion) {
7+
let nums = vec![42, 11, 1, 97];
8+
9+
c.bench_function("count_nice_pairs", |b| {
10+
b.iter(|| Solution::count_nice_pairs(black_box(nums.clone())))
11+
});
12+
}
13+
14+
fn bench_rev_implementations(c: &mut Criterion) {
15+
let mut group = c.benchmark_group("rev_implementations");
16+
17+
// Implementation 1: Loop-based
18+
fn rev_loop(mut num: i32) -> i32 {
19+
let mut result = 0;
20+
while num > 0 {
21+
result = result * 10 + num % 10;
22+
num /= 10;
23+
}
24+
result
25+
}
26+
27+
// Implementation 2: String-based
28+
fn rev_string(num: i32) -> i32 {
29+
num.to_string()
30+
.chars()
31+
.rev()
32+
.collect::<String>()
33+
.parse()
34+
.unwrap()
35+
}
36+
37+
let test_numbers = [42, 1234, 9876543, 1_000_000_000];
38+
39+
for &num in &test_numbers {
40+
group.bench_function(format!("loop_based_{}", num), |b| {
41+
b.iter(|| rev_loop(black_box(num)))
42+
});
43+
44+
group.bench_function(format!("string_based_{}", num), |b| {
45+
b.iter(|| rev_string(black_box(num)))
46+
});
47+
}
48+
49+
group.finish();
50+
}
51+
52+
criterion_group!(benches, bench_count_nice_pairs, bench_rev_implementations);
53+
criterion_main!(benches);

src/problems/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub mod p1431_kids_with_the_greatest_number_of_candies;
2424
pub mod p1464_maximum_product_of_two_elements_in_an_array;
2525
pub mod p1599_maximum_profit_of_operating_a_centennial_wheel;
2626
pub mod p1784_check_if_binary_string_has_at_most_one_segment_of_ones;
27+
pub mod p1814_count_nice_pairs_in_an_array;
2728
pub mod p1866_number_of_ways_to_rearrange_sticks_with_k_sticks_visible;
2829
pub mod p1876_substrings_of_size_three_with_distinct_characters;
2930
pub mod p1974_minimimum_time_to_type_word_using_special_typewriter;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//! # LeetCode Problem: 1814 - Count Nice Pairs in an Array
2+
//!
3+
//! ## Description
4+
//!
5+
//! Difficulty: Medium
6+
//!
7+
//! Link: https://leetcode.com/problems/count-nice-pairs-in-an-array/
8+
//!
9+
//! ## Complexity Analysis
10+
//! - Time Complexity: O(n) - We traverse the list containing n elements exactly twice.
11+
//! - Space Complexity: O(n) - We use a HashMap to store the frequency of each modified number.
12+
13+
pub struct Solution;
14+
15+
use std::collections::HashMap;
16+
17+
impl Solution {
18+
pub fn count_nice_pairs(nums: Vec<i32>) -> i32 {
19+
const MOD: i64 = 1_000_000_007;
20+
21+
// For comparison of the loop-based and string-based reverting functions,
22+
// see benchmark /benches/p1814_benchmark.rs
23+
// You can execute the benchmarks by running `cargo bench`
24+
fn rev(mut num: i32) -> i32 {
25+
let mut result = 0;
26+
while num > 0 {
27+
result = result * 10 + num % 10;
28+
num /= 10;
29+
}
30+
result
31+
}
32+
33+
// Count frequencies of differences in one pass
34+
let mut diff_counts: HashMap<i32, i64> = HashMap::new();
35+
for num in nums {
36+
let diff = num - rev(num);
37+
*diff_counts.entry(diff).or_insert(0) += 1;
38+
}
39+
// Calculate combinations: n choose 2 = n * (n - 1) / 2
40+
let mut result: i64 = 0;
41+
for &count in diff_counts.values() {
42+
if count >= 2 {
43+
result = (result + (count * (count - 1) / 2)) % MOD;
44+
}
45+
}
46+
47+
result as i32
48+
}
49+
}
50+
51+
#[cfg(test)]
52+
mod tests {
53+
use super::Solution;
54+
55+
#[test]
56+
fn test_count_nice_pairs() {
57+
let test_cases = [(vec![42, 11, 1, 97], 2), (vec![13, 10, 35, 24, 76], 4)];
58+
for (idx, (nums, expected)) in test_cases.iter().enumerate() {
59+
let result = Solution::count_nice_pairs(nums.clone());
60+
assert_eq!(
61+
result, *expected,
62+
"Test case #{idx}: with input {nums:?}, expected {expected:?}, got {result:?}"
63+
);
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)