zoukankan      html  css  js  c++  java
  • 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))
    
  • 相关阅读:
    IOS总结_无需自己定义UITabbar也可改变UITabbarController的背景和点击和的颜色
    破解中国电信华为无线猫路由(HG522-C)自己主动拨号+不限电脑数+iTV
    HDUJ 2074 叠筐 模拟
    CSRF——攻击与防御
    Ant命令行操作
    C#软件开发实例.私人订制自己的屏幕截图工具(七)加入放大镜的功能
    qemu-kvm-1.1.0源代码中关于迁移的代码分析
    FileSystemWatcher使用方法具体解释
    configure交叉编译
    海量图片存储策略
  • 原文地址:https://www.cnblogs.com/tmortred/p/13118059.html
Copyright © 2011-2022 走看看