|  | 
|  | 1 | +struct Solution; | 
|  | 2 | + | 
|  | 3 | +#[derive(Clone)] | 
|  | 4 | +struct Bucket { | 
|  | 5 | +    min: Option<i32>, | 
|  | 6 | +    max: Option<i32>, | 
|  | 7 | +} | 
|  | 8 | + | 
|  | 9 | +// https://leetcode.com/problems/maximum-gap | 
|  | 10 | +impl Solution { | 
|  | 11 | +    pub fn maximum_gap(nums: Vec<i32>) -> i32 { | 
|  | 12 | +        let n = nums.len() as i32; | 
|  | 13 | + | 
|  | 14 | +        if n < 2 { | 
|  | 15 | +            return 0; | 
|  | 16 | +        } | 
|  | 17 | + | 
|  | 18 | +        let max_val = nums.iter().max().unwrap(); | 
|  | 19 | +        let min_val = nums.iter().min().unwrap(); | 
|  | 20 | + | 
|  | 21 | +        if min_val == max_val { | 
|  | 22 | +            return 0; | 
|  | 23 | +        } | 
|  | 24 | + | 
|  | 25 | +        // (a + b - 1) / b is integer math for ceil(a / b) | 
|  | 26 | +        let bucket_size = ((max_val - min_val) + (n - 2)) / (n - 1); | 
|  | 27 | +        let bucket_count = (max_val - min_val) / bucket_size + 1; | 
|  | 28 | + | 
|  | 29 | +        let mut buckets = vec![ | 
|  | 30 | +            Bucket { | 
|  | 31 | +                min: None, | 
|  | 32 | +                max: None | 
|  | 33 | +            }; | 
|  | 34 | +            bucket_count as usize | 
|  | 35 | +        ]; | 
|  | 36 | + | 
|  | 37 | +        for &number in &nums { | 
|  | 38 | +            let index = ((number - min_val) / bucket_size) as usize; | 
|  | 39 | +            let bucket = &mut buckets[index]; | 
|  | 40 | +            bucket.min = Some(bucket.min.map_or(number, |min| min.min(number))); | 
|  | 41 | +            bucket.max = Some(bucket.max.map_or(number, |max| max.max(number))); | 
|  | 42 | +        } | 
|  | 43 | + | 
|  | 44 | +        let mut max_diff = 0; | 
|  | 45 | + | 
|  | 46 | +        let mut prev_max = None; | 
|  | 47 | +        for bucket in buckets { | 
|  | 48 | +            if let (Some(min), Some(max)) = (bucket.min, bucket.max) { | 
|  | 49 | +                if let Some(prev) = prev_max { | 
|  | 50 | +                    max_diff = max_diff.max(min - prev); | 
|  | 51 | +                } | 
|  | 52 | +                prev_max = Some(max); | 
|  | 53 | +            } | 
|  | 54 | +        } | 
|  | 55 | + | 
|  | 56 | +        max_diff | 
|  | 57 | +    } | 
|  | 58 | + | 
|  | 59 | +    pub fn maximum_gap_inefficient(nums: Vec<i32>) -> i32 { | 
|  | 60 | +        if nums.len() < 2 { | 
|  | 61 | +            return 0; | 
|  | 62 | +        } | 
|  | 63 | + | 
|  | 64 | +        let mut nums = nums; | 
|  | 65 | +        nums.sort(); | 
|  | 66 | + | 
|  | 67 | +        let mut min_diff = 0; | 
|  | 68 | + | 
|  | 69 | +        for window in nums.windows(2) { | 
|  | 70 | +            min_diff = min_diff.max(window[1] - window[0]); | 
|  | 71 | +        } | 
|  | 72 | + | 
|  | 73 | +        min_diff | 
|  | 74 | +    } | 
|  | 75 | +} | 
|  | 76 | + | 
|  | 77 | +#[test] | 
|  | 78 | +fn test() { | 
|  | 79 | +    let test_cases = [(vec![3, 6, 9, 1], 3), (vec![10], 0), (vec![0, 0, 0], 0)]; | 
|  | 80 | + | 
|  | 81 | +    for (nums, expected) in test_cases { | 
|  | 82 | +        assert_eq!( | 
|  | 83 | +            Solution::maximum_gap(nums.clone()), | 
|  | 84 | +            expected, | 
|  | 85 | +            "failed for nums {nums:?}", | 
|  | 86 | +        ); | 
|  | 87 | +        assert_eq!( | 
|  | 88 | +            Solution::maximum_gap_inefficient(nums.clone()), | 
|  | 89 | +            expected, | 
|  | 90 | +            "failed for nums {nums:?}", | 
|  | 91 | +        ); | 
|  | 92 | +    } | 
|  | 93 | +} | 
0 commit comments