Skip to content

Commit 461e478

Browse files
committed
Add problem 3043: Find the Length of the Longest Common Prefix
1 parent 3ef33d3 commit 461e478

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,6 +2058,7 @@ pub mod problem_3033_modify_the_matrix;
20582058
pub mod problem_3035_maximum_palindromes_after_operations;
20592059
pub mod problem_3038_maximum_number_of_operations_with_the_same_score_i;
20602060
pub mod problem_3039_apply_operations_to_make_string_empty;
2061+
pub mod problem_3043_find_the_length_of_the_longest_common_prefix;
20612062

20622063
#[cfg(test)]
20632064
mod test_utilities;
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
pub struct Solution;
2+
3+
// ------------------------------------------------------ snip ------------------------------------------------------ //
4+
5+
use std::collections::HashSet;
6+
use std::mem;
7+
8+
impl Solution {
9+
fn div_mod(lhs: u32, rhs: u32) -> (u32, u32) {
10+
(lhs / rhs, lhs % rhs)
11+
}
12+
13+
fn to_digits(value: u32) -> (u64, u8) {
14+
let mut result = 0;
15+
let mut length = 0;
16+
let mut value = value;
17+
let mut shift = 0_u8;
18+
19+
while value != 0 {
20+
let digit;
21+
22+
(value, digit) = Self::div_mod(value, 10);
23+
result |= u64::from(digit) << shift;
24+
length += 1;
25+
shift += 4;
26+
}
27+
28+
(result, length)
29+
}
30+
31+
fn to_digits_vec(values: Vec<i32>) -> (Vec<u64>, u8) {
32+
let mut max_length = 0;
33+
34+
let digits_vec = values
35+
.into_iter()
36+
.map(|value| {
37+
let (digits, length) = Self::to_digits(value.cast_unsigned());
38+
39+
max_length = max_length.max(length);
40+
41+
digits | (u64::from(length) << 60)
42+
})
43+
.collect();
44+
45+
(digits_vec, max_length)
46+
}
47+
48+
fn iter_digits(digits: &[u64], prefix_length: u8) -> impl Iterator<Item = u64> {
49+
digits.iter().filter_map(move |&digits| {
50+
let length = (digits >> 60) as u8;
51+
52+
if length < prefix_length {
53+
None
54+
} else {
55+
Some((digits & !(0b_1111 << 60)) >> ((length - prefix_length) * 4))
56+
}
57+
})
58+
}
59+
60+
fn check(digits_1: &[u64], digits_2: &[u64], buffer: &mut HashSet<u64>, middle: u8) -> bool {
61+
buffer.extend(Self::iter_digits(digits_1, middle));
62+
63+
let result = Self::iter_digits(digits_2, middle).any(|digits| buffer.contains(&digits));
64+
65+
buffer.clear();
66+
67+
result
68+
}
69+
70+
pub fn longest_common_prefix(arr1: Vec<i32>, arr2: Vec<i32>) -> i32 {
71+
let mut arr1 = arr1;
72+
let mut arr2 = arr2;
73+
74+
if arr2.len() < arr1.len() {
75+
mem::swap(&mut arr1, &mut arr2);
76+
}
77+
78+
let (digits_1, max_length_1) = Self::to_digits_vec(arr1);
79+
let (digits_2, max_length_2) = Self::to_digits_vec(arr2);
80+
let mut left = 1;
81+
let mut right = max_length_1.min(max_length_2) + 1;
82+
let mut buffer = HashSet::new();
83+
84+
while left != right {
85+
let middle = left.midpoint(right);
86+
87+
if Self::check(&digits_1, &digits_2, &mut buffer, middle) {
88+
left = middle + 1;
89+
} else {
90+
right = middle;
91+
}
92+
}
93+
94+
i32::from(left - 1)
95+
}
96+
}
97+
98+
// ------------------------------------------------------ snip ------------------------------------------------------ //
99+
100+
impl super::Solution for Solution {
101+
fn longest_common_prefix(arr1: Vec<i32>, arr2: Vec<i32>) -> i32 {
102+
Self::longest_common_prefix(arr1, arr2)
103+
}
104+
}
105+
106+
#[cfg(test)]
107+
mod tests {
108+
#[test]
109+
fn test_solution() {
110+
super::super::tests::run::<super::Solution>();
111+
}
112+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
pub mod binary_search;
2+
3+
pub trait Solution {
4+
fn longest_common_prefix(arr1: Vec<i32>, arr2: Vec<i32>) -> i32;
5+
}
6+
7+
#[cfg(test)]
8+
mod tests {
9+
use super::Solution;
10+
11+
pub fn run<S: Solution>() {
12+
let test_cases = [
13+
((&[1, 10, 100] as &[_], &[1000] as &[_]), 3),
14+
((&[1, 2, 3], &[4, 4, 4]), 0),
15+
];
16+
17+
for ((arr1, arr2), expected) in test_cases {
18+
assert_eq!(S::longest_common_prefix(arr1.to_vec(), arr2.to_vec()), expected);
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)