昨天笔试VIPKID有一道关于整数拆分的题目,要求输出拆分后的序列,当时没有做出来,记录一下可以实现的想法:
题目示例:
从键盘读入一个数 n, 输出所有和为 n 的子序列和,包括 n
测试用例:
输入 5
输出:
1 + 1 + 1 + 1 + 1
1 + 1 + 1 + 2
1 + 1 + 3
1 + 2 + 2
1 + 4
2 + 3
5
解题思路:首先这类需要不断分解的题目,首先想到的是递归法,也就是说将一个大数不断的分解为小数,然后将每一个分解的子数保存在一个 list 中,退出条件为当 n 的值减为 0,然后输出 list 中的值。
def resolve(n, minFlag):
global resCnt
global resList
global p
if n == 0:
resCnt += 1
for i in range(p):
print(resList[i], end="")
if i == p-1: # 当输出到最后一个数字时,不输出 '+'
continue
else:
print("+", end="")
print("")# 输出list中的值以后,换行
for i in range(minFlag, n+1):
resList[p] = i
p += 1
resolve(n-i, i)
p -= 1
if __name__ == '__main__':
# n = int(input())
n = 5
resCnt = 0# 记录子序列的个数
resList = [0] * n
minFlag = 1# 为了保证不重复,维护一个minFlag,来确保每次拆分后的最小值
p = 0
resolve(n, minFlag)
之前在写这道程序题时,使用n, m两个数来做递归。初始值 n = m。
然后每次做判断:
当 n=1 or m = 1 时:
当 n = 1, 直接输出1, 当 m = 1 时,输出 n 个1
当 n = m 时,调用递归函数 divideNum(n, m-1) + 1
当 n < m 时,divideNum(n, n)
当 n > m 时,也分为两种情况:
(1) 第一种 divideNum(n, m-1)
(2) 第二种 divideNum(n-m, n),将这两种的结果相加。
当时通过这种思路来解时,不知道如何输出分解的子序列,只能得出能够分解子序列的个数。
今天上午重新考虑了递归的思路,记录一下能够实现的方法。