competitive_programming_rs/math/
next_permutation.rs1pub trait NextPermutation {
2 fn next_permutation(&mut self) -> bool;
3}
4
5impl<T> NextPermutation for [T]
6where
7 T: PartialOrd,
8{
9 fn next_permutation(&mut self) -> bool {
10 if self.len() < 2 {
11 return false;
12 }
13
14 let mut i = self.len() - 1;
15 while i > 0 && self[i - 1] >= self[i] {
16 i -= 1;
17 }
18
19 if i == 0 {
20 return false;
21 }
22
23 let mut j = self.len() - 1;
24 while j >= i && self[j] <= self[i - 1] {
25 j -= 1;
26 }
27
28 self.swap(j, i - 1);
29 self[i..].reverse();
30 true
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use super::NextPermutation;
37 use std::collections::BTreeSet;
38
39 #[test]
40 fn test_next_permutation() {
41 let mut x = vec![1, 2, 3, 4, 5];
42 let mut set = BTreeSet::new();
43 let mut count = 0;
44 while x.next_permutation() {
45 count += 1;
46 set.insert(x.clone());
47 }
48 assert_eq!(count + 1, 5 * 4 * 3 * 2);
49 assert_eq!(set.len(), count);
50 }
51}