问题描述

给定一个数组及数字 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 ] ]

相关资源

k-sum 问题的更多相关文章

  1. summary of k Sum problem and solutions in leetcode

    I found summary of k Sum problem and solutions in leetcode on the Internet. http://www.sigmainfy.com ...

  2. lintcode: k Sum 解题报告

    K SUM My Submissions http://www.lintcode.com/en/problem/k-sum/ 题目来自九章算法 13% Accepted Given n distinc ...

  3. k Sum | & ||

    k Sum Given n distinct positive integers, integer k (k <= n) and a number target. Find k numbers ...

  4. 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)

    转自  http://tech-wonderland.net/blog/summary-of-ksum-problems.html 前言: 做过leetcode的人都知道, 里面有2sum, 3sum ...

  5. K Sum(2 Sum,3 Sum,4 Sum,3-Sum Closest)

    算是经典算法问题了.这里主要针对只存在一个解或者只需要求一个解的情况描述一下解题思路.若需要找到所有可能解,方法需要略作调整.如有问题,欢迎指正. 2 sum: 如果已排序,可直接用夹逼法,即两指针从 ...

  6. LeetCode解题报告--2Sum, 3Sum, 4Sum, K Sum求和问题总结

    前言: 这几天在做LeetCode 里面有2sum, 3sum(closest), 4sum等问题, 这类问题是典型的递归思路解题.该这类问题的关键在于,在进行求和求解前,要先排序Arrays.sor ...

  7. 2019年南京网络赛E题K Sum(莫比乌斯反演+杜教筛+欧拉降幂)

    目录 题目链接 思路 代码 题目链接 传送门 思路 首先我们将原式化简: \[ \begin{aligned} &\sum\limits_{l_1=1}^{n}\sum\limits_{l_2 ...

  8. 南京网络赛 E K Sum

    K Sum 终于过了这玩意啊啊啊==== 莫比乌斯反演,杜教筛,各种分块,积性函数怎么线性递推还很迷==,得继续研究研究 #include<bits/stdc++.h> using nam ...

  9. 2019南京网络赛E:K Sum

    Description: 定义函数 \[ f _n (k) = \sum _{l _1 = 1} ^n \sum _{l _2 = 1} ^n \cdots \sum _{l _k = 1} ^n \ ...

  10. Leetcode - K Sum

    List<List<Integer>> kSum_Trim(int[] a, int target, int k) { List<List<Integer>& ...

随机推荐

  1. CreateRemoteThread 远程注入

    在release中可以成功,在debug中被注入的程序停止工作 #pragma once#include "stdafx.h"#include <windows.h># ...

  2. Debian 7开启ssh、telnet

    SSH 1. 安装ssh服务 apt-get install openssh-server 2. 开启ssh /etc/init.d/ssh  start Telnet 1. 安装telnet apt ...

  3. CentOS 7.2 部署Rsync + Lsyncd服务实现文件实时同步/备份 (二)

    发送端配置: 一.配置密钥 1. 主/从服务器之间启用基于密钥的身份验证.登录发送端服务器并用 " ssh-keygen " 命令生成公共或私有的密钥. 2. 使用 " ...

  4. Mysql 不存在则插入,存在则更新

    )) BEGIN ) ; END 开始写了一大堆的代码来实现,原来还有这种方法,惊讶~~~ 如果不存在,就插入一条数据:如果存在,更新某个字段. on duplicate key update: my ...

  5. DAY7-面向对象之继承与派生

    一.初识继承 什么是继承 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类. 子类会“”遗传”父类的属性,从而解决代 ...

  6. net.sf.fjep.fatjar_0.0.32 eclipse4.x 可以用的jar包

    http://pan.baidu.com/s/1nvlIw21?errno=0&errmsg=Auth%20Login%20Sucess&stoken=bb98db9f451c00ae ...

  7. android viewpage解决嵌套

    子viewpage 自定义 写法一: public class ChildViewPager extends ViewPager{ /** 触摸时按下的点 **/ PointF downP = new ...

  8. 【总结整理】json数据请求简化版理解(祺哥的成果)

    在同源js目录下新建.txt文件 { "news":[ {"title":"审计管理","time":"201 ...

  9. c#日期与字符串间的转换(转)

    1.日期转字符串(转载) 在编程中经常要用到将日期变量转换为字符串的情况,而且不同的时候希望转换成不同格式的字符串 下面是一些常用的转换及转换结果: (查看格式说明) 以日期为例: 2009-09-0 ...

  10. Codeforces 960F 线段树

    题意:https://blog.csdn.net/qq_39809664/article/details/79871282 思路:我们考虑LIS的状态转移,对于这个题,假设现在扫描到的边是(u, v, ...