You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Luca Lombardo e05536a993 new problems 1 year ago
..
src new problems 1 year ago
Cargo.toml new problems 1 year ago
README.md new problems 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)
}