2023-07-02:给定一个 1~N 的排列,每次将相邻两数相加,可以得到新的序列,长度是 N-1 再对新的序列,每次将相邻两数相加,可以得到新的序列,长度是 N-2 这样下去可以最终只剩一个数字 比如 :
2023-07-02:给定一个 1~N 的排列,每次将相邻两数相加,可以得到新的序列,长度是 N-1
再对新的序列,每次将相邻两数相加,可以得到新的序列,长度是 N-2
这样下去可以最终只剩一个数字
比如 :
3 1 2 4
4 3 6
7 9
16
现在如果知道 N,和最后的数字 sum,反推最原始的序列是什么
如果有多个答案,返回字典序最小的那个
字典序看做所有数字拼起来的字符串字典序
比如
1, 10, 2... 拼起来是 1102...
1, 2, 3, 4... 拼起来是 1234...
认为 1, 10, 2...的字典序更小
如果给定的 n 和 sum,有答案,返回一个 N 长度的答案数组
如果给定的 n 和 sum,无答案,返回一个 1 长度的数组{ -1 }
输入 : N = 4, sum = 16
输出 : 3 1 2 4
输入 : N = 10, sum = 4116
输出 : 1 3 5 7 10 9 8 6 4 2
答案 2023-07-02:
大体步骤如下:
1.创建一个二维动态数组dp
,大小为(1<<(n+1))
x(sums[n]+1)
。
2.定义一个变量status
,其初始值为((1 << (n + 1)) - 1) ^ 1
。
3.如果n
小于 1 或大于 10,或者sum
大于sums[n]
,则返回数组[-1]
。
4.调用process
函数处理状态status
、剩余和rest
、索引index
、长度n
、模数组modulus
和动态数组dp
,得到结果ans
。
5.如果ans
的值为-1,说明无法找到合适的序列,返回数组[-1]
。
6.创建一个长度为n
的答案数组ans
,并初始化index
为 0,rest
为sum
。
7.当status
不等于 0 时,执行以下循环:
将
dp[status][rest]
的值赋给ans[index]
。将
status
异或上1 << ans[index]
,更新status
。将
rest
减去ans[index] * modulus[index]
,更新rest
。将
index
加 1。
8.返回答案数组ans
。
总的时间复杂度:O(2^N * sum),其中 N 为输入的 n,sum 为输入的 sum。总的空间复杂度:O(2^N * sum),包括二维动态数组 dp 的空间。
go 语言代码如下:
版权声明: 本文为 InfoQ 作者【福大大架构师每日一题】的原创文章。
原文链接:【http://xie.infoq.cn/article/a3a6718918c512caa74b01bb9】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论