-
Notifications
You must be signed in to change notification settings - Fork 0
/
partition_equal_subset_sum.rs
103 lines (79 loc) · 2.38 KB
/
partition_equal_subset_sum.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::collections::HashMap;
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
struct State {
index: usize,
target: i64,
}
impl State {
fn new(index: usize, target: i64) -> Self {
Self { index, target }
}
fn with(&self, value: i64) -> Self {
Self::new(self.index + 1, self.target - value)
}
fn without(&self) -> Self {
Self::new(self.index + 1, self.target)
}
}
/// Given an integer array `nums`, return `true` if you can partition the array into two subsets
/// such that the sum of the elements in both subsets is equaled or `false` otherwise.
struct Solution;
impl Solution {
fn calculate_sum(nums: &Vec<i32>) -> i64 {
let mut result = 0;
for &num in nums {
result += num as i64;
}
result
}
fn worker(results: &mut HashMap<State, bool>, nums: &Vec<i32>, state: State) -> bool {
let mut result = false;
if results.contains_key(&state) {
results[&state]
} else {
let n = nums.len();
let value = nums[state.index] as i64;
if state.index == n-1 {
if value == state.target {
result = true;
} else if value == 0 {
result = true;
} else {
result = false;
}
} else {
result = result || Self::worker(results, nums, state.with(value));
result = result || Self::worker(results, nums, state.without());
}
results.insert(state, result);
result
}
}
pub fn can_partition(nums: Vec<i32>) -> bool {
let mut result = false;
let sum = Self::calculate_sum(&nums);
if sum % 2 == 0 {
let target = sum / 2;
let initial_state = State::new(0, target);
let mut results = HashMap::new();
result = Self::worker(&mut results, &nums, initial_state);
}
result
}
}
#[cfg(test)]
mod tests {
use super::Solution;
#[test]
fn example_1() {
let nums = vec![1,5,11,5];
let result = Solution::can_partition(nums);
assert!(result);
}
#[test]
fn example_2() {
let nums = vec![1,2,3,5];
let result = Solution::can_partition(nums);
assert!(!result);
}
}