[Python] Well commented solution with easy to follow recursion
\nclass Solution(object):\n    def numDupDigitsAtMostN(self, N):\n        """\n        :type N: int\n        :rtype: int\n        """\n        memo = {}\n      
```\nclass Solution(object):\n    def numDupDigitsAtMostN(self, N):\n        """\n        :type N: int\n        :rtype: int\n        """\n        memo = {}\n        def f(digits_of_N, i, digits_used, any_digit):\n            if i == k:\n                return 1\n            \n            key = (i, digits_used, any_digit)\n            if key in memo:\n                return memo[key]\n            \n            # For each digit position, we iterate through all possible choices\n            cnt = 0\n            # If it\'s the leading digit, at position 0, we cannot pick 0 as a choice\n            min_digit = 1 if i == 0 else 0\n            # We can pick up to and including the digit at the i-th position of N so\n            # the number stays <= N. However if we\'ve picked some previous digit less\n            # than that in N at the same position, then we can pick any digit we want.\n            # Why? Because if the more significant digit has a smaller number, it doesn\'t\n            # matter what number we pick for less sigificant digit positions.\n            max_digit = 9 if any_digit else digits_of_N[i]\n            for d in range(min_digit, max_digit + 1):\n                # Use a bitmask to record if we\'ve already used a digit. Since we only want\n                # integers with unique digits, once a digit is used, it cannot be picked again.\n                if digits_used & (1 << d) != 0:\n                    continue\n                # If we picked some digit less than the i-th digit of N, then for the\n                # digit positions after i we can pick whatever we want, as long as\n                # the digit picked is unique, and it will be less than N. \n                cnt += f(digits_of_N, i + 1, digits_used | (1 << d), any_digit or (d < digits_of_N[i]))\n            \n            memo[key] = cnt\n            return cnt\n        \n        # Life is easier without having to deal with the single-digit case.\n        # It\'s only interesting when we have at least 2 digits.\n        if N <= 9:\n            return 0\n        \n        # Let k be the number of digits in N\n        k = len(str(N))\n        # We break the set of positive integers <= N with at least one duplicate digit into \n        # two disjoint sets A and B, where:\n        #   - A is the set of positive integers with k - 1 or less number of digits, with at least 1\n\t\t#       duplicate digit\n        #   - B is the set of positive integers <= N with exactly k number of digits, with at least 1\n\t\t#      duplicate digit\n        \n        # Let\'s first count the size A.\n        # Given i in [1.. k - 1], the set of positive integers with i digits and at least 1 duplicate digit\n\t\t# must be:\n        #    The set of positive integers with i digits - positive integers with only unique digits.\n        # Well positive integers with i digits is just 9 * 10^(i - 1) -- we have {1, 2 .. 9} as \n        # possible choices for the leading digit and then {0..9} as possible choices for each of the \n        # remaining digits. \n        # And positive integers with i digits and only unique digits must be:\n        #    9 * 9 * 8 * 7 ... up to i terms\n        # We have {1..9} as possible choices for the leading digit and then 10 - 1 possible choices\n        # for the second digit -- whatever leading digit we picked we cannot select that again.\n        # And having made a choice for the second digit, we\'d then only have 8 possible choices \n        # for the 3rd digit and so on, until we have only 1 possible digit choice left.\n        cnt = 0\n        for i in range(1, k):\n            all_possible_ints = 9 * 10**(i-1)\n            ints_with_unique_digits = 9\n            nb_choices = 9\n            for j in range(1, i):\n                ints_with_unique_digits *= nb_choices\n                nb_choices -= 1\n            cnt += all_possible_ints - ints_with_unique_digits\n            \n        # Let\'s then count the size of B. Again it\'s similar to A.\n        # For positive integers with exactly k digits <= N. e.g. if N = 12483, then \n        # we have 12483 - 9999 possible integers with 5 digits. (9999 or below are all\n        # numbers with less than 5 digits)\n        all_ints_with_k_digits = N - int(\'9\'*(k-1))\n        # To count the number of positive integers <= N with exactly k unique digits,\n        # we\'ll need a bit of recursion. See comments in f()\n        digits_of_N = [int(d) for d in str(N)]\n        ints_with_unique_k_digits = f(digits_of_N, 0, 0, False)\n        cnt += all_ints_with_k_digits - ints_with_unique_k_digits\n        \n        return cnt\n```
[]