累加和为 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. Ceph创建一个新集群 报错: File "/usr/bin/ceph-deploy", line 18, in..........

    [root@ceph-node1 ceph]# ceph-deploy new node1 Traceback (most recent call last): File "/usr/bin ...

  2. ArkUI 页面路由

    很多应用由多个页面组成,不同的页面承担着不一样的功能.比如,从音乐列表页面点击歌曲,跳转到该歌曲的播放界面.开发者需要通过页面路由将这些页面串联起来. 在 js -> default -> ...

  3. C++ 文件hash值 BT种子的hash值

    这个两个东东,是我在网上找到的.小小的修改了一下方便大家使用. 一个是 获取文件哈希值的,另外一个是获取torrent文件磁力链接的哈希值. 整理好的类下载地址: 文件hash值: http://pa ...

  4. 有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成。

    有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成. 分析:线性表中关于逆序的问题,就是用建立链表的头插法.而本题要求不能建立新 ...

  5. 「题解报告」SP16185 Mining your own business

    题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...

  6. Linux之LVM逻辑卷管理

    LVM逻辑卷管理 LVM机制:PV物理卷,VG卷组,LV逻辑卷. --功能-- --物理卷管理-- --卷组管理-- --逻辑卷管理-- create(建立) pvcreate vgcreate lv ...

  7. RTSP播放器开发填坑之道

    好多开发者提到,在目前开源播放器如此泛滥的情况下,为什么还需要做自研框架的RTSP播放器,自研和开源播放器,到底好在哪些方面?以下大概聊聊我们的一点经验,感兴趣的,可以关注 github: 1. 低延 ...

  8. rtmp/rtsp/hls公网测试地址

    相信大家在调试播放器的时候,都有这样的困惑,很难找到合适的公有测试源,以下是大牛直播整理的真正可用的直播地址源. 其中,rtmp和rtsp的url,用https://github.com/daniul ...

  9. plpgsql 编译执行

    Oracle 的存储过程或函数提供了两种执行方式: 解释执行:将源代码逐条转换成目标代码,解释一条,执行一条的过程.PLPGSQL将语句翻译成中间形式的系统代码,并在运行时进行解释. 编译执行:将源代 ...

  10. Git Bash(提交文件到GitHub进行托管)

    ​ Introduction 使用Git Bash命令,可以将一个项目上传到Github官网中,进行托管,避免重要文件被误删 1.Git工具下载 Git for Windows 2.在github中新 ...