-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.rs
71 lines (66 loc) · 2.01 KB
/
main.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
fn main() {
let a = vec![1,2,3,1,2,3];
let x = a[0..3] == a[3..];
println!("x = {:#?}", x);
assert_eq!(Solution::three_equal_parts(vec![1,0,1,0,1]), [0,3]);
}
struct Solution {}
impl Solution {
/// intuition: there must be same number of 1 in each part
/// so there is only one possible solution, no need to simulate
/// use math to simplify the problem
/// Tag [Math]
/// O(n) algorithm
pub fn three_equal_parts(a: Vec<i32>) -> Vec<i32> {
// count the number of ones
let n = a.len();
let ones = a.iter().filter(|&x| *x == 1).count();
if ones == 0 { return vec![0, 2] }
if ones % 3 != 0 { return vec![-1,-1] }
let ones = ones / 3;
let (i1, i2, i3, j1, j2, j3);
let mut i = 0;
let mut cnt = 0;
while a[i] == 0 { i += 1 }
i1 = i; // start of 1 inclusive
while cnt < ones {
if a[i] == 1 { cnt += 1 }
i += 1;
}
j1 = i; // end of 1 exclusive
while a[i] == 0 { i += 1 }
i2 = i;
cnt = 0;
while cnt < ones {
if a[i] == 1 { cnt += 1 }
i += 1;
}
j2 = i;
while a[i] == 0 { i += 1 }
i3 = i;
cnt = 0;
while cnt < ones {
if a[i] == 1 { cnt += 1 }
i += 1;
}
j3 = i;
let z = n - j3; // number of pending zeros
if j1+z > i2 || j2+z > i3 { return vec![-1,-1] }
if a[i1..j1+z] != a[i2..j2+z] || a[i2..j2+z] != a[i3..] { return vec![-1,-1] }
vec![j1+z-1, j2+z].into_iter().map(|x| x as i32).collect()
}
}
#[cfg(test)]
mod test {
use crate::*;
#[test]
fn basic() {
assert_eq!(Solution::three_equal_parts(vec![1,0,1,0,1]), [0,3]);
assert_eq!(Solution::three_equal_parts(vec![1,1,0,1,1]), [-1,-1]);
}
#[test]
fn fail() {
assert_eq!(Solution::three_equal_parts(vec![1,1,1,1,1,1]), [1,4]);
assert_eq!(Solution::three_equal_parts(vec![0,0,0,0,0,0]), [0,2]);
}
}