累加和为 K 的子数组问题

作者:Grey

原文地址:

博客园:累加和为 K 的子数组问题

CSDN:累加和为 K 的子数组问题

题目说明

数组全为正数,且每个数各不相同,求累加和为K的子数组组合有哪些,

注:数组中同一个数字可以无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

题目链接见:LeetCode 39. Combination Sum

主要思路

使用动态规划来解,定义如下递归函数

List<List<Integer>> p(int[] arr, int len, int i, int k)

递归含义表示:数组从 i 开始,一直到最后,可以得到的子数组满足数组之和等于 k 的子数组组合有哪些。

首先是 base case

        if (i == len) {
return new ArrayList<>();
}
List<List<Integer>> ans = new ArrayList<>();
if (k == 0) {
ans.add(new ArrayList<>());
return ans;
}

当 i 到数组结尾位置下一个位置,说明,i 到头了,不能继续往后找了,直接返回一个空列表,

当 k 等于 0,直接返回一个包含空列表的列表,表示一个数也没有,组合之和等于 0。

接下来是普遍情况,枚举每个位置有 times 个的情况下,往后收集的集合数是多少,即

for (int times = 0; times * arr[i] <= k; times++) {
// 每个位置有 times 的情况下,往后收集的集合个数
}

由于数组中全是正数,所以前提是: times * arr[i] <= k

如果times * arr[i]正好等于 k,说明收集到了一个满足条件的集合,这个集合里面有 times 个 arr[i]

for (int times = 0; times * arr[i] <= k; times++) {
// 每个位置有 times 的情况下,往后收集的集合个数
if (times * arr[i] == k) {
List<Integer> t = new ArrayList<>();
// 收集到了一种情况,即集合里面有 times 个 arr[i]
for (int j = 0; j < times; j++) {
t.add(arr[i]);
}
ans.add(t);
return ans;
}
……
}

接下来就是当前位置 i 搞定 times * arr[i],i + 1 以后的数组搞定k - times * arr[i]

        for (int times = 0; times * arr[i] <= k; times++) {
if (times * arr[i] == k) {
List<Integer> t = new ArrayList<>();
for (int j = 0; j < times; j++) {
t.add(arr[i]);
}
ans.add(t);
return ans;
}
// 剩下的位置搞定 k - arr[i] * times
for (List<Integer> a : p(arr, len, i + 1, k - times * arr[i])) {
for (int j = 0; j < times; j++) {
a.add(arr[i]);
}
ans.add(a);
}
}
return ans;

完整代码如下

class Solution {

    // 从i号位置开始及其后面的所有,帮我搞定target
public static List<List<Integer>> combinationSum(int[] arr, int k) {
return p(arr, arr.length, 0, k);
} // 从i号位置开始及其后面的所有,帮我搞定target
private static List<List<Integer>> p(int[] arr, int len, int i, int k) { if (i == len) {
return new ArrayList<>();
}
List<List<Integer>> ans = new ArrayList<>();
if (k == 0) {
ans.add(new ArrayList<>());
return ans;
} for (int times = 0; times * arr[i] <= k; times++) {
if (times * arr[i] == k) {
List<Integer> t = new ArrayList<>();
for (int j = 0; j < times; j++) {
t.add(arr[i]);
}
ans.add(t);
return ans;
}
for (List<Integer> a : p(arr, len, i + 1, k - times * arr[i])) {
for (int j = 0; j < times; j++) {
a.add(arr[i]);
}
ans.add(a);
}
}
return ans;
}
}

更多

算法和数据结构笔记

最新文章

  1. sql 语句
  2. CentOS7 虚拟机搭建、初始设置、简单使用
  3. Eclipse/JavaWeb (三)三大框架之Spring框架 持续更新中...
  4. Rxjava的基本使用
  5. css3 github javascript
  6. [LintCode] Left Pad 左填充
  7. bookshelf
  8. Sencha Toucha 2 —1.环境安装配置、在线打包、离线打包
  9. Mac搭建Git/GitHub全过程
  10. Python爬虫:常用浏览器的useragent
  11. node源码详解 (一)
  12. iOS 中的类属性
  13. ZAB协议与Paxos算法
  14. nginx的The page you are looking for is temporarily unavailable错误解决办法
  15. python_day1_变量
  16. JS数组冒泡排序&amp;去重
  17. 使用vuejs做一个todolist
  18. Apache提供的dbUtils
  19. 微信小程序-获取当前城市位置及再次授权地理位置
  20. SharePoint 2016 工作流报错“未安装应用程序管理共享服务代理”

热门文章

  1. Flutter-填平菜鸟和高手之间的沟壑
  2. Mybatis简单入门--插入数据
  3. MySQL事务概念与流程和索引控制
  4. 定制化JDK升级引发的离奇事件
  5. C#基础_理解类
  6. 【java】学习路线8-cmd带命令编译包
  7. SpringBoot集成Thymeleaf发送Html邮件报错
  8. GB/T 28181联网系统通信协议结构和技术实现
  9. 使用『jQuery』『原生js』制作一个选项卡盒子 —— { }
  10. 重要参考步骤---ProxySQL Cluster 集群搭建步骤