Leetcode: 902. Numbers At Most N Given Digit Set

Posted tmortred

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode: 902. Numbers At Most N Given Digit Set相关的知识,希望对你有一定的参考价值。

descption

We have a sorted set of digits D, a non-empty subset of {‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘}.  (Note that ‘0‘ is not included.)

Now, we write numbers using these digits, using each digit as many times as we want.  For example, if D = {‘1‘,‘3‘,‘5‘}, we may write numbers such as ‘13‘, ‘551‘, ‘1351315‘.

Return the number of positive integers that can be written (using the digits of D) that are less than or equal to N.

Example

Input: D = ["1","3","5","7"], N = 100
Output: 20
Explanation: 
The 20 numbers that can be written are:
1, 3, 5, 7, 11, 13, 15, 17, 31, 33, 35, 37, 51, 53, 55, 57, 71, 73, 75, 77.

Note

D is a subset of digits ‘1‘-‘9‘ in sorted order.
1 <= N <= 10^9

分析

假设输入为 ["1","3","5","7"], N = 100, ssum 为输出结构
ssum = 所有的 2 位 数 + 所有的 1 位数 + 小于 100 的三位数个数
思路很简单,就是处理 corner case 花了很长时间

code

class Solution(object):
    def atMostNGivenDigitSet(self, ll, num):
        ll = [int(i) for i in ll]
        
        n, digits = num, []
        while n > 0:
            digits.append(n%10)
            n = int(n/10)
        digits.reverse()
        
        helper = [[0]*10 for i in range(len(digits))]
        
        for k, v in enumerate(ll):
            helper[0][v] = k+1
            
        for level in range(1, len(digits)):
            for i in range(10):
                if helper[0][i] == 0:
                    continue
                helper[level][i] = helper[0][i]* (len(ll) ** (level))

        def getsum(mlevel):
            ssum = 0
            for level in range(0, mlevel):
                ssum += max(helper[level])
            return ssum
                
        if ll[0] > digits[0]:
            return getsum(len(digits)-1)
            
        if digits[0] > ll[-1]:
            return getsum(len(digits))
        ssum = 0
        
        for index, v in enumerate(digits):
            if ll[0] > v:
                return ssum + getsum(len(digits)-index-1)
            if v > ll[-1]:
                return ssum + getsum(len(digits)-index)

            m = max(helper[0][:v+1])
            if index == len(digits) -1:
                return ssum +m
            
            if helper[0][v] == 0:
                return ssum + getsum(len(digits)-index-1) + m*len(ll) ** (len(digits)-index-1)
            
            ssum += m*max(helper[len(digits)-2-index])
                
        return ssum

总结

You are here!
Your runtime beats 94.29 % of python submissions.
You are here!
Your memory usage beats 31.43 % of python submissions.
  • 美中不足的是, 第一名的代码比我还少。而且我没看懂~
第一名的代码
class Solution:
    def atMostNGivenDigitSet(self, D, N):
        S = str(N)
        K = len(S)
        dp = [0] * K + [1]
        # dp[i] = total number of valid integers if N was "N[i:]"

        for i in xrange(K-1, -1, -1):
            # Compute dp[i]

            for d in D:
                if d < S[i]:
                    dp[i] += len(D) ** (K-i-1)
                elif d == S[i]:
                    dp[i] += dp[i+1]

        return dp[0] + sum(len(D) ** i for i in xrange(1, K))

以上是关于Leetcode: 902. Numbers At Most N Given Digit Set的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 0902. 最大为 N 的数字组合「抽象出了函数,看着较为明白的代码 + 手推」

由最多N个给定数字集组成的数字 Numbers At Most N Given Digit Set

Add Two Numbers ---- LeetCode

LeetCode Lexicographical Numbers

[LeetCode] Consecutive Numbers 连续的数字

Leetcode 2. Add Two Numbers