k-sum 问题
栏目: JavaScript · 发布时间: 5年前
内容简介:给定一个数组及数字 k ,从数组中找出所有相加结果为 k 的组合。示例:给定数组
问题描述
给定一个数组及数字 k ,从数组中找出所有相加结果为 k 的组合。
示例:
给定数组 [1,1,1]
令 k=2
,输出:
[[1,1]]
给定数组 [10, 1, 2, 7, 6, 1, 5]
令 k=8
,输出:
[ [ 1, 2, 5 ], [ 1, 7 ], [ 1, 1, 6 ], [ 2, 6 ] ]
分析
这里的思路是把 k
逐步拆解。既然要找出相加等于 k
的元素,那根据递归的思想,不难想到假如已经找到了数组中一个有效的元素,那么接下来就是从剩余的元素中继续去找,相加等于 k
减去该元素的那些组合,形成了一个新的子问题。
所以对于第一个结果的查找,可以从索引为 0 的位置开始遍历数组:
-
从候选数据
arr
中取出第一个元素item0
,这样得到了一个取出该元素后的新数组arr1
, -
从
k
中减去该元素item0
得到一个新的k0
。 -
如此往复,接下来任务就是需要在新的数组
arr1
中找出一个组合,其相加结果为k0
。 -
最后必然会进行到
k
为零的时候,此时将前面取出的数组合一起便得到了一个结果。 - 如果数组都遍历完了,但 K 最终没有变成零,说明本次查找没有结果。
第二个结果:
- 上面查找结束,开始从原数组中第二个位置开始重复上面的步骤。
...
直到进行到数组的最后一个元素。将前面得到的结果组合后返回。
实现
根据上面的分析得出如下的实现:
/** * k-sum 实现,从候选数组中找出所有相加结果为 k 的组合 * @param {*} arr 候选数组 * @param {*} k 目标数字 */ function ksum(arr, k) { var result = []; function process(input, tmpK, tmpResult) { tmpResult = tmpResult || []; if (tmpK === 0 && tmpResult.length > 0) { tmpResult.sort((a, b) => a - b); var hasDuplicate = result.some(v => { return v.join("") === tmpResult.join(""); }); if (!hasDuplicate) { result.push(tmpResult); } } else if (tmpK > 0) { for (let i = 0; i < input.length; i++) { const num = input[i]; process(input.slice(i + 1), tmpK - num, tmpResult.concat(num)); } } } process(arr, k); return result; }
测试:
console.log(ksum([1,1,1], 2)); // [ [ 1, 1 ] ] console.log(ksum([10, 1, 2, 7, 6, 1, 5], 8)); // [ [ 1, 2, 5 ], [ 1, 7 ], [ 1, 1, 6 ], [ 2, 6 ] ]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- acme.sh 续期问题(路径问题)
- 缓存的一些问题和一些加密算法【缓存问题】
- 如何把设计问题转化为数学问题(方法论)
- 推荐系统中的冷启动问题和探索利用问题
- GraphQL 教程(六)—— N+1问题和缓存等问题
- Golang 并发问题(四)之单核上的并发问题
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C++标准模板库编程实战
Ivor Horton / 郭小虎、程聪 / 2017-1
《C++标准模板库编程实战》介绍最新的C++14标准的API、库和扩展,以及如何将它们运用到C++14程序中。在书中,作者Ivor Horton 则阐述了什么是STL,以及如何将它们应用到程序中。我们将学习如何使用容器、迭代器,以及如何定义、创建和应用算法。此外,还将学习函数对象和适配器,以及它们的用法。 阅读完本书之后,你将能够了解如何扩展STL,如何定义自定义类型的C++组件,你还将能够......一起来看看 《C++标准模板库编程实战》 这本书的介绍吧!