-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathnon-decreasing-subsequences.rs
73 lines (71 loc) · 2.48 KB
/
non-decreasing-subsequences.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
// 491. Non-decreasing Subsequences
// 🟠 Medium
//
// https://leetcode.com/problems/non-decreasing-subsequences/
//
// Tags: Array - Hash Table - Backtracking - Bit Manipulation
struct Solution;
impl Solution {
// The classic backtracking solution to sub-sequence type problems. Start
// at the first element of the array and split into two branches, one
// that uses it and one that skips it, for each element after that, we
// chose to skip it and keep building the sequence and, if its value does
// not break the non-decreasing property of the sequence, we create
// another branch that uses the element.
//
// Time complexity: O(n*2^n) - The decision tree splits in two at each
// level and it has a max of n levels, for each of the 2^n possible
// sequences, we iterate over all its elements, a max of n, to convert
// them into a tuple hash them and add them to the hash set.
// Space complexity: O(n*2^n) - The number of subsequences that could be
// in the hash set.
//
// Runtime 19 ms Beats 100%
// Memory 5.6 MB Beats 44.44%
pub fn find_subsequences(nums: Vec<i32>) -> Vec<Vec<i32>> {
use std::collections::HashSet;
let mut res = HashSet::new();
let mut cur = vec![];
fn bt(idx: usize, cur: &mut Vec<i32>, res: &mut HashSet<Vec<i32>>, nums: &Vec<i32>) {
if idx == nums.len() {
// If the subsequence is not empty.
if cur.len() > 1 {
res.insert(cur.to_vec());
}
return;
}
// Keep building the sequence that skips this number.
bt(idx + 1, cur, res, nums);
// Try to unpack the last value.
if cur.is_empty() || cur[cur.len() - 1] <= nums[idx] {
cur.push(nums[idx]);
bt(idx + 1, cur, res, nums);
cur.pop();
}
}
bt(0, &mut cur, &mut res, &nums);
res.into_iter().collect()
}
}
// Tests.
fn main() {
assert_eq!(
Solution::find_subsequences(vec![4, 4, 3, 2, 1]).sort(),
vec![vec![4, 4]].sort()
);
assert_eq!(
Solution::find_subsequences(vec![4, 6, 7, 7]).sort(),
vec![
vec![4, 6],
vec![4, 6, 7],
vec![4, 6, 7, 7],
vec![4, 7],
vec![4, 7, 7],
vec![6, 7],
vec![6, 7, 7],
vec![7, 7],
]
.sort()
);
println!("All tests passed!")
}