-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
maximum_subarray.rs
82 lines (74 loc) · 2.73 KB
/
maximum_subarray.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! This module provides a function to find the largest sum of the subarray
//! in a given array of integers using dynamic programming. It also includes
//! tests to verify the correctness of the implementation.
/// Custom error type for maximum subarray
#[derive(Debug, PartialEq)]
pub enum MaximumSubarrayError {
EmptyArray,
}
/// Finds the subarray (containing at least one number) which has the largest sum
/// and returns its sum.
///
/// A subarray is a contiguous part of an array.
///
/// # Arguments
///
/// * `array` - A slice of integers.
///
/// # Returns
///
/// A `Result` which is:
/// * `Ok(isize)` representing the largest sum of a contiguous subarray.
/// * `Err(MaximumSubarrayError)` if the array is empty.
///
/// # Complexity
///
/// * Time complexity: `O(array.len())`
/// * Space complexity: `O(1)`
pub fn maximum_subarray(array: &[isize]) -> Result<isize, MaximumSubarrayError> {
if array.is_empty() {
return Err(MaximumSubarrayError::EmptyArray);
}
let mut cur_sum = array[0];
let mut max_sum = cur_sum;
for &x in &array[1..] {
cur_sum = (cur_sum + x).max(x);
max_sum = max_sum.max(cur_sum);
}
Ok(max_sum)
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! maximum_subarray_tests {
($($name:ident: $tc:expr,)*) => {
$(
#[test]
fn $name() {
let (array, expected) = $tc;
assert_eq!(maximum_subarray(&array), expected);
}
)*
}
}
maximum_subarray_tests! {
test_all_non_negative: (vec![1, 0, 5, 8], Ok(14)),
test_all_negative: (vec![-3, -1, -8, -2], Ok(-1)),
test_mixed_negative_and_positive: (vec![-4, 3, -2, 5, -8], Ok(6)),
test_single_element_positive: (vec![6], Ok(6)),
test_single_element_negative: (vec![-6], Ok(-6)),
test_mixed_elements: (vec![-2, 1, -3, 4, -1, 2, 1, -5, 4], Ok(6)),
test_empty_array: (vec![], Err(MaximumSubarrayError::EmptyArray)),
test_all_zeroes: (vec![0, 0, 0, 0], Ok(0)),
test_single_zero: (vec![0], Ok(0)),
test_alternating_signs: (vec![3, -2, 5, -1], Ok(6)),
test_all_negatives_with_one_positive: (vec![-3, -4, 1, -7, -2], Ok(1)),
test_all_positives_with_one_negative: (vec![3, 4, -1, 7, 2], Ok(15)),
test_all_positives: (vec![2, 3, 1, 5], Ok(11)),
test_large_values: (vec![1000, -500, 1000, -500, 1000], Ok(2000)),
test_large_array: ((0..1000).collect::<Vec<_>>(), Ok(499500)),
test_large_negative_array: ((0..1000).map(|x| -x).collect::<Vec<_>>(), Ok(0)),
test_single_large_positive: (vec![1000000], Ok(1000000)),
test_single_large_negative: (vec![-1000000], Ok(-1000000)),
}
}