Algorithm 通过从整数列表中添加最少数量的元素来获取整数
给定一个整数列表Algorithm 通过从整数列表中添加最少数量的元素来获取整数,algorithm,kotlin,recursion,Algorithm,Kotlin,Recursion,给定一个整数列表[2,3],我想实现那些加起来等于8的数字的最佳组合。结果应该是[3,3,2]。下面的代码工作正常 fun getbestcomposition(targetSum:Int,number:Array) :可变列表?{ if(targetSum==0)返回mutableListOf() if(targetSum
[2,3]
,我想实现那些加起来等于8
的数字的最佳组合。结果应该是[3,3,2]
。下面的代码工作正常
fun getbestcomposition(targetSum:Int,number:Array)
:可变列表?{
if(targetSum==0)返回mutableListOf()
if(targetSum<0)返回null
变量最佳组合:可变列表?=null
for(数字中的数字){
val newTarget=targetSum-编号
val结果=getBestCombination(新目标,数字)
结果呢?让我来{
it.add(数字)
if(it.size<最佳组合?.size?:it.size+1){
最佳组合=它
}
}
}
返回最佳组合
}
此代码生成正确的结果[3,3,2]
但上述代码的时间复杂度是指数级的。当我试图缓存来自重复递归节点的结果时,它不起作用。下面的代码产生了[3,3,2,2,3]
我不明白为什么
fun GetBestCombination优化(
targetSum:Int,
数字:数组,
内存:HashMap=hashMapOf()
):可变列表?{
//查看存储的结果
if(memory.containsKey(targetSum))返回内存[targetSum]
if(targetSum==0)返回mutableListOf()
if(targetSum<0)返回null
变量最佳组合:可变列表?=null
for(数字中的数字){
val newTarget=targetSum-编号
val结果=getBestCombinationOptimized(新目标、数字、内存)
结果呢?让我来{
it.add(数字)
if(it.size<最佳组合?.size?:it.size+1){
最佳组合=它
}
}
}
//缓存结果
内存[targetSum]=最佳组合
返回最佳组合
}
您的问题称为NP完全问题。因此,您不太可能找到最坏情况下的多项式时间算法。这是针对您的特定情况的伪代码工作解决方案:
n = 8
dist = (INF, INF, 0, 0, ..., 0) /* size n + 1 */
last = (0, 0, ..., 0) /* size n + 1 */
//dynamic programming step: filling array
for i = 4, ..., n :
| if dist[i - 2] < dist[i - 3] :
| | dist[i] = 1 + dist[i - 2]
| | last[i] = i - 2
|
| else :
| | dist[i] = 1 + dist[i - 3]
| | last[i] = i - 3
//going back through the solution
while n != 2 and n != 3:
| if n - last[n] == 2 :
| | print(2)
| | n = n - 2
|
| else :
| | print(3)
| | n = n - 3
print(n)
n=8
dist=(INF,INF,0,0,…,0)/*大小n+1*/
最后=(0,0,…,0)/*大小n+1*/
//动态规划步骤:填充数组
对于i=4,…,n:
|如果dist[i-2]
输出:3 2
这个想法是填充从2到n的所有数字(在第一种情况下,n=8),将“距离”存储在
dist
中,并将上一步存储在last
中,用于告诉您到达n的路径。我终于在代码中找到了问题。问题出在我编写的代码的以下部分bestcomposition=it
。在这里,每当出现一个新的最少元素组合时,我都会一遍又一遍地分配相同的列表对象引用(it
)。因此,我将元素添加到完全相同的列表中。我真正需要做的是复制元素,然后将其分配给bestcomposition
,从而防止在同一个列表对象上循环
result?.let {
it.add(number)
if (it.size < bestCombination?.size ?: it.size + 1) {
//--------- CULPRIT ----------//
bestCombination = it
//----------------------------//
}
}
我真是个白痴谢谢大家把时间花在这个愚蠢的错误上。所谓“最佳组合”,是指最少的术语吗?是的。最少术语。这是一个教科书动态规划问题。这个问题用Kotlin标记。你为什么提供C++答案?一种语言的习语不一定能翻译成另一种语言,因为我不认识科特林。另一方面,该算法是通用的,可以很容易地翻译为任何接受数组概念的语言,没有任何错误,转换应该是直接和快速的。然后我礼貌地建议花时间学习kotlin,而不是提供一个可能不相关的答案。即使Kotlin支持数组,语言提供的特性也非常不同,并将其自身应用到C++中不容易访问的解决方案中。一种语言的工作并不意味着它在另一种语言中能很好地工作。“丹尼尔,你可以编写这个算法,而不是C++。
bestCombination = it.toMutableList()