1
+ /**
2
+ * Here I show how you can generate all the combinations of a sequence of size r which are repeated
3
+ * at most k times.
4
+ *
5
+ * <p>Time Complexity: O(n+r-1 choose r) = O((n+r-1)!/(r!(n-1)!))
6
+ *
7
+ * @author William Fiset, william.alexandre.fiset@gmail.com
8
+ */
9
+ package com .williamfiset .algorithms .other ;
10
+
11
+ public class CombinationsWithRepetition {
12
+
13
+ /**
14
+ * Computes all combinations of elements of 'r' elements which can be repeated at most 'k' times
15
+ * each.
16
+ *
17
+ * @param sequence - The sequence containing all the elements we wish to take combinations from
18
+ * @param usedCount - Tracks how many of each element we currently have selected
19
+ * @param at - The current position we're at in the sequence
20
+ * @param r - The number of elements we're choosing
21
+ * @param k - The maximum number of times each element is allowed to be picked
22
+ */
23
+ private static void combinationsWithRepetition (
24
+ int [] sequence , int [] usedCount , int at , int r , int k ) {
25
+
26
+ final int N = sequence .length ;
27
+
28
+ // We reached the end
29
+ if (at == N ) {
30
+
31
+ // We selected 'r' elements in total
32
+ if (r == 0 ) {
33
+
34
+ // Print combination
35
+ System .out .print ("{ " );
36
+ for (int i = 0 ; i < N ; i ++)
37
+ for (int j = 0 ; j < usedCount [i ]; j ++) System .out .print (sequence [i ] + " " );
38
+ System .out .println ("}" );
39
+ }
40
+
41
+ } else {
42
+
43
+ // For this particular time at position 'at' try including it each of [0, k] times
44
+ for (int itemCount = 0 ; itemCount <= k ; itemCount ++) {
45
+
46
+ // Try including this element itemCount number of times (this is possibly more than once)
47
+ usedCount [at ] = itemCount ;
48
+
49
+ combinationsWithRepetition (sequence , usedCount , at + 1 , r - itemCount , k );
50
+ }
51
+ }
52
+ }
53
+
54
+ // Given a sequence this method prints all the combinations of size
55
+ // 'r' in a given sequence which has each element repeated at most 'k' times
56
+ public static void printCombinationsWithRepetition (int [] sequence , int r , int k ) {
57
+
58
+ if (sequence == null ) return ;
59
+ final int n = sequence .length ;
60
+ if (r > n ) throw new IllegalArgumentException ("r must be <= n" );
61
+ if (k > r ) throw new IllegalArgumentException ("k must be <= r" );
62
+
63
+ int [] usedCount = new int [sequence .length ];
64
+ combinationsWithRepetition (sequence , usedCount , 0 , r , k );
65
+ }
66
+
67
+ public static void main (String [] args ) {
68
+
69
+ // Prints all combinations of size 3 where
70
+ // each element is repeated at most twice
71
+ int [] seq = {1 , 2 , 3 , 4 };
72
+ printCombinationsWithRepetition (seq , 3 , 2 );
73
+ // prints:
74
+ // { 3 4 4 }
75
+ // { 3 3 4 }
76
+ // { 2 4 4 }
77
+ // { 2 3 4 }
78
+ // { 2 3 3 }
79
+ // { 2 2 4 }
80
+ // { 2 2 3 }
81
+ // { 1 4 4 }
82
+ // { 1 3 4 }
83
+ // { 1 3 3 }
84
+ // { 1 2 4 }
85
+ // { 1 2 3 }
86
+ // { 1 2 2 }
87
+ // { 1 1 4 }
88
+ // { 1 1 3 }
89
+ // { 1 1 2 }
90
+
91
+ }
92
+ }
0 commit comments