@@ -111,3 +111,59 @@ const canDistribute = function(nums, quantity) {
111111 return dp [ idx ] [ mask ] = res
112112 }
113113} ;
114+
115+ // another
116+
117+ /**
118+ * @param {number[] } nums
119+ * @param {number[] } quantity
120+ * @return {boolean }
121+ */
122+ const canDistribute = function ( nums , quantity ) {
123+ const hash = { }
124+ for ( const e of nums ) {
125+ if ( hash [ e ] == null ) hash [ e ] = 0
126+ hash [ e ] ++
127+ }
128+ const cnts = Object . values ( hash ) , m = quantity . length , n = cnts . length
129+ const dp = Array . from ( { length : n } , ( ) => Array ( 1 << m ) . fill ( null ) )
130+
131+ return helper ( 0 , 0 )
132+
133+ function helper ( idx , mask ) {
134+ // mask are already selected candidates
135+ if ( mask == ( 1 << m ) - 1 ) {
136+ return true ;
137+ }
138+ if ( idx == n ) {
139+ return false ;
140+ }
141+ if ( dp [ idx ] [ mask ] != null ) {
142+ return dp [ idx ] [ mask ] ;
143+ }
144+ let ans = helper ( idx + 1 , mask ) ;
145+
146+ for ( let i = 1 ; i < ( 1 << m ) ; ++ i ) {
147+ // i are potential candidates in addition to already selected ones (from mask)
148+ // if i == mask, we can skip as the candidate is selected already
149+ // if mask != (mask & i) means that this candidate does not include selected ones e.g
150+ // mask = 3 (i.e 2 elements 1,2 in binary) and i = 4 (the third element in binary as 4 does not include 1 & 2), there we skip
151+ if ( mask == i || mask != ( mask & i ) ) continue ;
152+ let sum = 0 ;
153+ for ( let j = 0 ; j < m ; ++ j ) {
154+ // mask << ~j is just a fancy way to do: if(mask & (1 << j)) that i've learned from @Uwi and this way you don't have to use "(", ")"
155+ // what it does is simply pushing the jth bit to the 2^31 bit which is negative
156+ // thus if the jth bit is 1 then the value is less than zero and if its 0 then its greater or equal to zero
157+ if ( mask << ~ j >= 0 && i << ~ j < 0 ) { // check that mask does not contain the new candidate and that the candidate is part of the potential candidate i
158+ sum += quantity [ j ] ;
159+ }
160+ }
161+ if ( sum <= cnts [ idx ] ) {
162+ ans |= helper ( idx + 1 , i ) ;
163+ }
164+ if ( ans ) break ; // if ans is true, then a solution exists and no further computation is required
165+ }
166+ dp [ idx ] [ mask ] = ans ;
167+ return ans ;
168+ }
169+ }
0 commit comments