累加和为 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;
}
}

更多

算法和数据结构笔记

累加和为 K 的子数组问题的更多相关文章

  1. Java实现 LeetCode 713 乘积小于K的子数组(子集数量+双指针)

    713. 乘积小于K的子数组 给定一个正整数数组 nums. 找出该数组内乘积小于 k 的连续的子数组的个数. 示例 1: 输入: nums = [10,5,2,6], k = 100 输出: 8 解 ...

  2. Java实现 LeetCode 560 和为K的子数组(某著名排序大法改编)

    560. 和为K的子数组 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] ...

  3. [LeetCode]560. 和为K的子数组(前缀和)

    题目 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] 为 ...

  4. LeetCode 560. Subarray Sum Equals K (子数组之和等于K)

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

  5. [Swift]LeetCode560. 和为K的子数组 | Subarray Sum Equals K

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

  6. [Swift]LeetCode713. 乘积小于K的子数组 | Subarray Product Less Than K

    Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...

  7. 66.Subarray Sum Equals K(子数组和为K的个数)

    Level:   Medium 题目描述: Given an array of integers and an integer k, you need to find the total number ...

  8. 560. Subarray Sum Equals K 求和为k的子数组个数

    [抄题]: Given an array of integers and an integer k, you need to find the total number of continuous s ...

  9. [LeetCode] Subarray Sum Equals K 子数组和为K

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

随机推荐

  1. vue中axios配置代理的俩种方式及优缺点

    概述:Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中 当我们使用vue向服务器发送AJAX请求时,我们会遇到跨域问题,一般跨域的解决方案有俩种,一种是官 ...

  2. ZJU-199001 第三周练习 2 数字特征值 位运算算法

    题目 对数字求特征值是常用的编码算法,奇偶特征是一种简单的特征值. 对于一个整数, 从个位开始对每一位数字编号, 个位是 \(1\) 号, 十位是 \(2\) 号, 以此类推. 这个整数在第位上的数字 ...

  3. 1.6_HTML基础属性

    name 属性 name 属性用于指定标签元素的名称. <a> 标签内必须提供 href 或 name 属性. <a name="value"> id 属性 ...

  4. rh358 003 ansible部署双网卡绑定 DNS原理 bind正向解析

    双网卡绑定 绑定多张网卡成为逻辑口,从而实现链路冗余,以及数据流量的负载均衡 1.创建team口 [root@servera ~]# nmcli connection add type team co ...

  5. 【读书笔记】C#高级编程 第十三章 异步编程

    (一)异步编程的重要性 使用异步编程,方法调用是在后台运行(通常在线程或任务的帮助下),并不会阻塞调用线程.有3中不同的异步编程模式:异步模式.基于事件的异步模式和新增加的基于任务的异步模式(TAP, ...

  6. 干货分享!JAVA诊断工具Arthas在Rainbond上实践~

    别再担心线上 Java 业务出问题怎么办了,Arthas 帮助你解决以下常见问题: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执行到?难道是我没 ...

  7. C语言的几个入门关于函数调用练习

    1.找素数(素数:除了1和本身之外不能被任何整数整除的的数)(被某数整除=除以某数是整数) 问题:输出2到200(包括2和200)的使有素数,从小到大排序. 思路:检查所有比i小的数,取余. 涉及的知 ...

  8. Java安全之Velocity模版注入

    Java安全之Velocity模版注入 Apache Velocity Apache Velocity是一个基于Java的模板引擎,它提供了一个模板语言去引用由Java代码定义的对象.它允许web 页 ...

  9. 使用sonarqube对java项目进行分析

    目前有两种办法,第一种是使用SonarQube-Scanner-Maven,第二种是结合gitlab-ci进行 前提条件:已安装并启动sonarqube,知道访问地址和登录的用户名及密码,具体参考文档 ...

  10. 在 Linux 上为特定的用户或用户组启用或禁用 SSH

    由于你的公司标准规定,你可能只能允许部分人访问 Linux 系统.或者你可能只能够允许几个用户组中的用户访问 Linux 系统.那么如何实现这样的要求呢?最好的方法是什么呢?如何使用一个简单的方法去实 ...