当前位置: 首页 > news >正文

小于n的最大数 Leetcode 902 Numbers At Most N Given Digit Set

这两个问题的本质就是一个棵树,然后根据n对树做剪枝。难点在于剪的时候边界条件有些坑,get_lower_largest_digit_dic是这两个题目的共同点

题目一: 小于n的最大数

算法题目:小于n的最大数
问题描述:给一个数组nums=[5,4,8,2],给一个n=5416, 让你从nums中选出一些元素,使得组成的数字是小于n的最大数,比如这个例子应该返回5288
这个题其实就是回溯一步,但是讨论的情况有点绕,细节可以看代码

class Solution:
    def get_num(self, candidates, num):
        max_str = str(max(list(candidates)))
        num_str = str(num)
        def get_lower_largest_digit_dic(candidates):
            dic={}
            prev = None
            for i in range(10):
                dic[str(i)] = prev
                if i in candidates:
                    prev = str(i)
            return dic
        lower_largest_digit_dic = get_lower_largest_digit_dic(candidates)
        i,l = 0,len(num_str)
        res_str_arr = ['0' for i in range(l)]

        while(i<l):
            if int(num_str[i]) in candidates and i<l-1:
                # 第一阶段,相等的一直往后填
                res_str_arr[i] = num_str[i]
                i += 1
            else:
                # 第二阶段:遇到最后一个,或者没有相等的(也分为几种情况),统一填为lower_largest_digit,然后后面统一填最大
                digit = lower_largest_digit_dic[num_str[i]]
                while digit == None and i > 0: #一直找不到,一直回溯
                    i -= 1
                    digit = lower_largest_digit_dic[num_str[i]]
                # 按照while不成功的情况讨论下
                if i == 0 and digit == None and l == 1:
                    return None
                if i == 0 and digit == None and l > 1:
                    res_str_arr[0] = '0'
                else:
                    res_str_arr[i] = digit
                for j in range(i+1,l):
                    res_str_arr[j] = max_str
                return int(''.join(res_str_arr))

if __name__ == '__main__':
    s = Solution()
    print(s.get_num({1,2,9,4}, 2533))  # 2499
    print(s.get_num({1,2,5,4}, 2543))  # 2542
    print(s.get_num({1,2,5,4}, 2541))  # 2525
    print(s.get_num({1,2,9,4}, 2111))  # 1999
    print(s.get_num({5,9}, 5555)) #999

题目二: 最大为 N 的数字组合

来自https://leetcode.com/problems/numbers-at-most-n-given-digit-set/

Given an array of digits which is sorted in non-decreasing order. You can write numbers using each digits[i] as many times as we want. For example, if digits = [‘1’,‘3’,‘5’], we may write numbers such as ‘13’, ‘551’, and ‘1351315’.

Return the number of positive integers that can be generated that are less than or equal to a given integer n.

Example 1:

Input: digits = [“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.
Example 2:

Input: digits = [“1”,“4”,“9”], n = 1000000000
Output: 29523
Explanation:
We can write 3 one digit numbers, 9 two digit numbers, 27 three digit numbers,
81 four digit numbers, 243 five digit numbers, 729 six digit numbers,
2187 seven digit numbers, 6561 eight digit numbers, and 19683 nine digit numbers.
In total, this is 29523 integers that can be written using the digits array.
Example 3:

Input: digits = [“7”], n = 8
Output: 1

Constraints:

1 <= digits.length <= 9
digits[i].length == 1
digits[i] is a digit from ‘1’ to ‘9’.
All the values in digits are unique.
digits is sorted in non-decreasing order.
1 <= n <= 109

其实和题目一思路很相似,但是边界条件容易错:

class Solution:
    def atMostNGivenDigitSet(self, digits: List[str], n: int) -> int:
        def get_lt_digit_cnt_dic(digits_set):
            dic = {}
            prev = 0
            for i in range(0,10):
                stri = str(i)
                dic[stri] = prev
                if stri in digits_set:
                    prev += 1
            return dic

        digits_set = set(digits)
        lt_digit_cnt_dic = get_lt_digit_cnt_dic(digits_set)
        dl = len(digits)
        nl = len(str(n))

        factorial = [1 for i in range(nl)]
        for i in range(1,nl):
            factorial[i] = factorial[i-1]*dl
        res1 = sum(factorial[i] for i in range(1,nl))

        res2,i = 0,0
        strn = str(n)
        while i<nl:
            lt_digit_cnt = lt_digit_cnt_dic[strn[i]]
            res2 += lt_digit_cnt * factorial[nl-(i+1)]
            if (strn[i] not in digits_set):
                break
            i+=1
        # 这个条件容易漏掉,例如digits =["3","4","8"], n = 4
        if i == nl and strn[nl-1] in digits_set:
            res2 += 1
        # print(res1)
        return res1+res2

相关文章:

  • ISP代理和数据中心IP的不同
  • Git常用命令总结
  • shell的编写
  • Maven 项目之快速选择环境配置文件
  • NSSCTF Round#20 Basic 真亦假,假亦真 CSDN_To_PDF V1.2 出题笔记 (附wp+源码)
  • ajax的优缺点有哪些?
  • 即刻体验 | 使用 Flutter 3.19 更高效地开发
  • Ubuntu服务器搭建 - 环境篇
  • java八股——linux常见命令
  • 智慧工地安全+绿色施工方案
  • 【子集回溯】Leetcode 78. 子集 90. 子集 II
  • 文心一言 vs GPT-4 -- 全面横向比较
  • SpringBoot(48)-使用 SkyWalking 进行分布式链路追踪
  • Spark-Scala语言实战(11)
  • 【智能算法】蜜獾算法(HBA)原理及实现
  • 笔记: JavaSE day15 笔记
  • 百卓Smart管理平台 importexport.php SQL注入漏洞复现(CVE-2024-27718)
  • OSPF中配置静态路由负载分担实验简述
  • SpringBoot -- Profiles
  • 手机无线投屏到windows11电脑
  • 刘洪洁已任六安市委副书记、市政府党组书记
  • 近七成科创板公司2024年营收增长,285家营收创历史新高
  • 神舟十九号航天员乘组平安抵京
  • 首开股份:一季度净利润亏损约10.79亿元,签约金额63.9亿元
  • 国务院食安办:加强五一假期食品生产、销售、餐饮服务环节监管
  • 摩根大通任命杜峯为亚太区副主席,加码中国市场业务布局