Python Digit DP (Pattern For Similar Questions)
Theory: https://codeforces.com/blog/entry/53960\n\nMore of the same approach:\n902. Numbers At Most N Given Digit Set\n788. Rotated Digits\n1397. Find All Good 
Theory: https://codeforces.com/blog/entry/53960\n\nMore of the same approach:\n[902. Numbers At Most N Given Digit Set](https://leetcode.com/problems/numbers-at-most-n-given-digit-set/discuss/559624/python-digit-dp)\n[788. Rotated Digits](https://leetcode.com/problems/rotated-digits/discuss/560601/python-digit-dp)\n[1397. Find All Good Strings](https://leetcode.com/problems/find-all-good-strings/discuss/560841/Python-Digit-DP)\n[233. Number of Digit One](https://leetcode.com/problems/number-of-digit-one/discuss/560876/Python-Digit-DP)\n[357. Count Numbers with Unique Digits](https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/560898/Python-Digit-DP)\n[600. Non-negative Integers without Consecutive Ones](https://leetcode.com/problems/non-negative-integers-without-consecutive-ones/discuss/584350/Python-Digit-DP-(Pattern-For-Similar-Questions))\n\nAt each recursive call (adding digit to less significant position) compute:\n- isPrefix - if the new number is the prefix of N\n- isBigger - if the new number will be bigger than N when we reach final position\n- digits - current digits of the new number\n- repeated - if there is already a repeated digit\nOptimization - if there is already a repeated number and the current number cannot be bigger than N when we reach the last position we can add 10 (for 10 digits) to the result and every subresult gets multiplied by 10.\n```\n    def numDupDigitsAtMostN(self, N: int) -> int:\n        N = list(map(int, str(N)))\n\n        @functools.lru_cache(None)\n        def dp(pos, isPrefix, isBigger, digits, repeated):\n            if pos == len(N):\n                return 0\n            if repeated and not isPrefix and not isBigger:\n                return 10 + 10 * dp(pos + 1, False, False, digits, True)\n            result = 0\n            for i in range(0 if pos > 0 else 1, 10):\n                _isPrefix = isPrefix and i == N[pos]\n                _isBigger = isBigger or (isPrefix and i > N[pos])\n                _repeated = repeated\n                if (digits >> i) & 1 == 1:\n                    _repeated = True\n                if _repeated and not (pos == len(N) - 1 and _isBigger):\n                    result += 1\n                _digits = digits | (1 << i)\n                result += dp(pos + 1, _isPrefix, _isBigger, _digits, _repeated)\n            return result\n        return dp(0, True, False, 0, False)\n\t```
[]