@@ -58,3 +58,59 @@ const countSpecialNumbers = function (n) {
58
58
return ( dp [ idx ] [ tight ] [ mask ] = ans )
59
59
}
60
60
}
61
+
62
+ // another
63
+
64
+ const dp = Array . from ( { length : 11 } , ( ) =>
65
+ Array . from ( { length : 2 } , ( ) => Array ( 1024 ) . fill ( - 1 ) ) ,
66
+ )
67
+
68
+ function gogo ( s , tight = 1 , pos = 0 , mask = 0 ) {
69
+ // Base case
70
+ if ( pos === s . length ) {
71
+ // Mask = 0, represents 00000...0 which should not be counted
72
+ return mask !== 0
73
+ }
74
+
75
+ // DP state
76
+ if ( dp [ pos ] [ tight ] [ mask ] !== - 1 ) {
77
+ return dp [ pos ] [ tight ] [ mask ]
78
+ }
79
+
80
+ let ans = 0
81
+
82
+ if ( tight === 1 ) {
83
+ // Limit the current digit
84
+ for ( let i = 0 ; i <= s [ pos ] - '0' ; i ++ ) {
85
+ // Check if digit repeated, ie, present in the mask
86
+ if ( mask & ( 1 << i ) ) continue
87
+
88
+ const newMask = mask === 0 && i === 0 ? mask : mask | ( 1 << i )
89
+
90
+ if ( i === s [ pos ] - '0' ) {
91
+ // Tight case
92
+ ans += gogo ( s , 1 , pos + 1 , newMask )
93
+ } else {
94
+ ans += gogo ( s , 0 , pos + 1 , newMask )
95
+ }
96
+ }
97
+ } else {
98
+ for ( let i = 0 ; i <= 9 ; i ++ ) {
99
+ // Check if digit repeated, ie, present in the mask
100
+ if ( mask & ( 1 << i ) ) continue
101
+
102
+ const newMask = mask === 0 && i === 0 ? mask : mask | ( 1 << i )
103
+ ans += gogo ( s , 0 , pos + 1 , newMask )
104
+ }
105
+ }
106
+ return ( dp [ pos ] [ tight ] [ mask ] = ans )
107
+ }
108
+ /**
109
+ * @param {number } n
110
+ * @return {number }
111
+ */
112
+ var countSpecialNumbers = function ( n ) {
113
+ const s = n . toString ( )
114
+ dp . forEach ( ( arr ) => arr . forEach ( ( innerArr ) => innerArr . fill ( - 1 ) ) )
115
+ return gogo ( s )
116
+ }
0 commit comments