31ba3abfe4 | 1 year ago | |
---|---|---|
.. | ||
src | 1 year ago | |
Cargo.toml | 1 year ago | |
README.md | 1 year ago |
README.md
Comments on the solution
The problem requires finding the longest segment of an array that contains no more than k
different values. We can use a sliding window approach. We maintain a hashmap to store the count of each value in the current segment. We start with the left and right indices at 0 and keep incrementing the right index until the number of different values in the segment exceeds k
. At this point, we increment the left index until the number of different values in the segment is less than or equal to k
. We keep track of the maximum length of the segment seen so far and return the left and right indices of this segment.
Complexity analysis
-
Time complexity:
O(n)
since we only iterate through the array once and perform constant time operations on each element. -
Space complexity:
O(k)
since we store the count of each value in the hashmap.
Rust Solution
This version reads the input from stdin and writes the output to stdout (as required by the problem statement)
fn main() {
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
let mut iter = input.split_whitespace();
let n: usize = iter.next().unwrap().parse().unwrap();
let k: usize = iter.next().unwrap().parse().unwrap();
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
let mut iter = input.split_whitespace();
let mut a: Vec<usize> = Vec::with_capacity(n);
for _ in 0..n {
a.push(iter.next().unwrap().parse().unwrap());
}
let mut l = 0;
let mut r = 0;
let mut max = 0;
let mut map: std::collections::HashMap<usize, usize> = std::collections::HashMap::new();
while r < n {
let count = map.entry(a[r]).or_insert(0);
*count += 1;
while map.len() > k {
let count = map.entry(a[l]).or_insert(0);
*count -= 1;
if *count == 0 {
map.remove(&a[l]);
}
l += 1;
}
if r - l + 1 > max {
max = r - l + 1;
}
r += 1;
}
println!("{} {}", l + 1, r);
}
Here is a version that takes the input as arguments and returns the output as a tuple.
fn find_k_good_segment(n: usize, k: usize, a: &[usize]) -> (usize, usize) {
let mut l = 0;
let mut r = 0;
let mut max = 0;
let mut map: std::collections::HashMap<usize, usize> = std::collections::HashMap::new();
while r < n {
let count = map.entry(a[r]).or_insert(0);
*count += 1;
while map.len() > k {
let count = map.entry(a[l]).or_insert(0);
*count -= 1;
if *count == 0 {
map.remove(&a[l]);
}
l += 1;
}
if r - l + 1 > max {
max = r - l + 1;
}
r += 1;
}
(l + 1, r)
}