解决leetcode第3883题统计满足数位和数组的非递减数组数目

3883.统计满足数位和数组的非递减数组数目

难度:困难

问题描述:

给你一个长度为n的整数数组digitSum。

如果一个长度为n的数组arr满足以下条件,则认为它是有效的:

0<=arr[i]<=5000

它是非递减的。

arr[i]的数位和等于digitSum[i]。

返回一个整数,表示不同的有效数组的数量。由于答案可能很大,请将其对109+7取模后返回。

如果一个数组的每个元素都大于或等于它的前一个元素(如果存在),则称该数组是非递减的。

示例1:

输入:digitSum=[25,1]

输出:6

解释:

数位和为25的数字有799、889、898、979、988和997。

数位和为1且可以出现在这些值之后同时保持数组非递减的唯一数字是1000。

因此,有效数组为[799,1000]、[889,1000]、[898,1000]、[979,1000]、[988,1000]和[997,1000]。

因此,答案是6。

示例2:

输入:digitSum=[1]

输出:4

解释:

有效数组为[1]、[10]、[100]和[1000]。

因此,答案是4。

示例3:

输入:digitSum=[2,49,23]

输出:0

解释:

在范围[0,5000]内没有数位和为49的整数。因此,答案是0。

提示:

1<=digitSum.length<=1000

0<=digitSum[i]<=50

问题分析:

一种做法是,先把digits数组中的数字分解成数字和数组的形式,比如digits=[1,2],可以把组成数字和为1和2的所有数字找出构成一个数组[[1, 10, 100, 1000],[2, 11, 20, 101, 110, 200, 1001, 1010, 1100, 2000]],然后从[1, 10, 100, 1000]和[2, 11, 20, 101, 110, 200, 1001, 1010, 1100, 2000]中找出所有的非递减排列,如果后面还有数字和排列,则可以把这次的非递减排列的最后一个数字提取出来形成一个数组,然后用其中的元素与后面的数字和排列中的数字依次进行比较,从而可以构成新的非递减排列元素,直到得到最终结果。

程序如下:

python 复制代码
#对于给定的整数n,找出在【0,5000】中数位和等于n的所有整数并以列表形式返回
def get_digits(n):
    digits=[]
    for i in range(0, 5001):
        t = list(str(i))
        s = sum(list(map(int, t)))
        if s == n:
            digits.append(i)
    return digits

#将两个数组能够组成的所有非递减排列找出并返回,其中a为上一次生成的,b为新的数组
def get_all_non_decreasing_order_from_two_arrays(a,b):
    t =[]
    c=list(i[-1] for i in a)
    m=len(a)
    n=len(b)
    for i in range(m):
        for j in range(n):
            if c[i]<=b[j]:
                d=a[i]+[b[j]]
                t.append(d)
    return t


# 主程序
digitsum=eval(input('pls input digitsum='))

n=len(digitsum)
t=[]
for i in digitsum:
    t.append(get_digits(i))
temp=list([x] for x in t[0])
for i in range(1,n):
    a=temp
    b=t[i]
    temp=get_all_non_decreasing_order_from_two_arrays(a,b)
print('不同有效数组如下:')
for i in range(1,len(temp)+1):
    s=str(temp[i-1])
    if i%5==0:
        print('{:>20}'.format(s),end='\n')
    else:
        print('{:>20}'.format(s),end=' ')
print(f'\n共有不同有效数组共{len(temp)%(10**9+7)}个')

运行实例一

pls input digitsum=[2,3]

不同有效数组如下:

2, 3\] \[2, 12\] \[2, 21\] \[2, 30\] \[2, 102

2, 111\] \[2, 120\] \[2, 201\] \[2, 210\] \[2, 300

2, 1002\] \[2, 1011\] \[2, 1020\] \[2, 1101\] \[2, 1110

2, 1200\] \[2, 2001\] \[2, 2010\] \[2, 2100\] \[2, 3000

11, 12\] \[11, 21\] \[11, 30\] \[11, 102\] \[11, 111

11, 120\] \[11, 201\] \[11, 210\] \[11, 300\] \[11, 1002

11, 1011\] \[11, 1020\] \[11, 1101\] \[11, 1110\] \[11, 1200

11, 2001\] \[11, 2010\] \[11, 2100\] \[11, 3000\] \[20, 21

20, 30\] \[20, 102\] \[20, 111\] \[20, 120\] \[20, 201

20, 210\] \[20, 300\] \[20, 1002\] \[20, 1011\] \[20, 1020

20, 1101\] \[20, 1110\] \[20, 1200\] \[20, 2001\] \[20, 2010

20, 2100\] \[20, 3000\] \[101, 102\] \[101, 111\] \[101, 120

101, 201\] \[101, 210\] \[101, 300\] \[101, 1002\] \[101, 1011

101, 1020\] \[101, 1101\] \[101, 1110\] \[101, 1200\] \[101, 2001

101, 2010\] \[101, 2100\] \[101, 3000\] \[110, 111\] \[110, 120

110, 201\] \[110, 210\] \[110, 300\] \[110, 1002\] \[110, 1011

110, 1020\] \[110, 1101\] \[110, 1110\] \[110, 1200\] \[110, 2001

110, 2010\] \[110, 2100\] \[110, 3000\] \[200, 201\] \[200, 210

200, 300\] \[200, 1002\] \[200, 1011\] \[200, 1020\] \[200, 1101

200, 1110\] \[200, 1200\] \[200, 2001\] \[200, 2010\] \[200, 2100

200, 3000\] \[1001, 1002\] \[1001, 1011\] \[1001, 1020\] \[1001, 1101

1001, 1110\] \[1001, 1200\] \[1001, 2001\] \[1001, 2010\] \[1001, 2100

1001, 3000\] \[1010, 1011\] \[1010, 1020\] \[1010, 1101\] \[1010, 1110

1010, 1200\] \[1010, 2001\] \[1010, 2010\] \[1010, 2100\] \[1010, 3000

1100, 1101\] \[1100, 1110\] \[1100, 1200\] \[1100, 2001\] \[1100, 2010

1100, 2100\] \[1100, 3000\] \[2000, 2001\] \[2000, 2010\] \[2000, 2100

2000, 3000

共有不同有效数组共131个

运行实例二

pls input digitsum=[2]

不同有效数组如下:

2\] \[11\] \[20\] \[101\] \[110

200\] \[1001\] \[1010\] \[1100\] \[2000

共有不同有效数组共10个

运行实例三

pls input digitsum=[25,2]

不同有效数组如下:

799, 1001\] \[799, 1010\] \[799, 1100\] \[799, 2000\] \[889, 1001

889, 1010\] \[889, 1100\] \[889, 2000\] \[898, 1001\] \[898, 1010

898, 1100\] \[898, 2000\] \[979, 1001\] \[979, 1010\] \[979, 1100

979, 2000\] \[988, 1001\] \[988, 1010\] \[988, 1100\] \[988, 2000

997, 1001\] \[997, 1010\] \[997, 1100\] \[997, 2000\] \[1699, 2000

1789, 2000\] \[1798, 2000\] \[1879, 2000\] \[1888, 2000\] \[1897, 2000

1969, 2000\] \[1978, 2000\] \[1987, 2000\] \[1996, 2000

共有不同有效数组共34个

相关推荐
小比特_蓝光2 小时前
算法篇二----二分查找
java·数据结构·算法
李昊哲小课2 小时前
Python办公自动化教程 - openpyxl让Excel处理变得轻松
python·信息可视化·excel
Ulyanov2 小时前
Streamlit基础入门与快速原型开发
python·架构·系统仿真
田梓燊2 小时前
leetcode 56
java·算法·leetcode
源码之屋2 小时前
计算机毕业设计:Python出行数据智能分析与预测平台 Django框架 可视化 数据分析 PyEcharts 交通 深度学习(建议收藏)✅
人工智能·python·深度学习·数据分析·django·汽车·课程设计
2301_803554523 小时前
三大编程语言(Python/Go/C++)项目启动全解析
c++·python·golang
给自己做减法3 小时前
AI编程相关概念
人工智能·python·ai编程
仍然.3 小时前
多线程---阻塞队列收尾和线程池
java·开发语言·算法
_深海凉_3 小时前
LeetCode热题100-最长公共前缀
算法·leetcode·职场和发展