`
MouseLearnJava
  • 浏览: 467259 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

从一个整数数组中找出总和为S的所有子集

阅读更多
本文将记录实现“从一个整数数组中找出总和为S的所有子集”功能的两种方法。

1. 使用Stack来实现

2. 不借助Stack来实现。

使用Stack来实现

import java.util.Stack;

public class GetAllSubsetByStack {

	/** Set a value for target sum */
	public static final int TARGET_SUM = 15;

	private Stack<Integer> stack = new Stack<Integer>();

	/** Store the sum of current elements stored in stack */
	private int sumInStack = 0;

	public void populateSubset(final int[] data, int fromIndex, int endIndex) {

		if (sumInStack >= TARGET_SUM) {
			if (sumInStack == TARGET_SUM) {
				print(stack);
			}
			// there is no need to continue when we have an answer
			// because nothing we add from here on in will make it
			// add to anything less than what we have...
			return;
		}

		for (int currentIndex = fromIndex; currentIndex < endIndex; currentIndex++) {

			if (sumInStack + data[currentIndex] <= TARGET_SUM) {
				stack.push(data[currentIndex]);
				sumInStack += data[currentIndex];

				/*
				 * Make the currentIndex +1, and then use recursion to proceed
				 * further.
				 */
				populateSubset(data, currentIndex + 1, endIndex);
				sumInStack -= (Integer) stack.pop();
			}
		}
	}

	/**
	 * Print satisfied result. i.e. 15 = 4+6+5
	 */

	private void print(Stack<Integer> stack) {
		StringBuilder sb = new StringBuilder();
		sb.append(TARGET_SUM).append(" = ");
		for (Integer i : stack) {
			sb.append(i).append("+");
		}
		System.out.println(sb.deleteCharAt(sb.length() - 1).toString());
	}
}


方法调用的类:

public class Main {

	private static final int[] DATA = { 1, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 13,
			14, 15 };

	public static void main(String[] args) {
		GetAllSubsetByStack example = new GetAllSubsetByStack();
		example.populateSubset(DATA, 0, DATA.length);
	}
}


不借助Stack来实现

import java.util.Arrays;

public class GetAllSubsets {

	/** Set a value for target sum */
	public static final int TARGET_SUM = 15;

	public void populateSubset(final int[] data, int fromIndex,
			final int[] stack, final int stacklen, final int target) {
		if (target == 0) {
			// exact match of our target. Success!
			printResult(Arrays.copyOf(stack, stacklen));
			return;
		}

		while (fromIndex < data.length && data[fromIndex] > target) {
			// take advantage of sorted data.
			// we can skip all values that are too large.
			fromIndex++;
		}

		while (fromIndex < data.length && data[fromIndex] <= target) {
			// stop looping when we run out of data, or when we overflow our
			// target.
			stack[stacklen] = data[fromIndex];
			populateSubset(data, fromIndex + 1, stack, stacklen + 1, target
					- data[fromIndex]);
			fromIndex++;
		}
	}

	private void printResult(int[] copyOf) {
		StringBuilder sb = new StringBuilder();
		sb.append(TARGET_SUM).append(" = ");
		for (Integer i : copyOf) {
			sb.append(i).append("+");
		}
		System.out.println(sb.deleteCharAt(sb.length() - 1).toString());
	}
}


方法调用的类:
public class Main {

	private static final int[] DATA = { 1, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 13,
			14, 15 };

	public static void main(String[] args) {
		GetAllSubsets example = new GetAllSubsets();
		example.populateSubset(DATA, 0, new int[DATA.length], 0, 15);
	}
}



两种实现方法都会打印出如下的结果:

15 = 1+3+4+5+2
15 = 1+3+4+7
15 = 1+3+5+6
15 = 1+3+2+9
15 = 1+3+11
15 = 1+4+2+8
15 = 1+4+10
15 = 1+5+2+7
15 = 1+5+9
15 = 1+6+8
15 = 1+14
15 = 3+4+6+2
15 = 3+4+8
15 = 3+5+7
15 = 3+2+10
15 = 4+5+6
15 = 4+2+9
15 = 4+11
15 = 5+2+8
15 = 5+10
15 = 6+2+7
15 = 6+9
15 = 2+13
15 = 7+8
15 = 15


转载请注明出处: http://mouselearnjava.iteye.com/blog/1985360
2
0
分享到:
评论
1 楼 hailongshih 2013-12-05  
算法还是有些没看懂,先Mark了再说

相关推荐

    c# 数据组合 从一组数据中 返回组合的和等于某个值 的所有组合

    这段代码定义了`FindCombinations`函数,它接受一个整数数组和一个目标值,然后调用私有辅助函数`FindHelper`进行递归操作。`FindHelper`函数负责处理实际的组合生成,并通过回溯来尝试不同的选择。 总结来说,"c# ...

    数据集目录,其中 包含子集和问题的示例,其中一组 给出数字,并且希望找到至少一个子集 总和为给定的目标值.rar

    问题的输入通常包括一个整数数组和一个目标值T,任务是找出数组中是否存在一个子集,使得子集中所有元素的和等于目标值T。这个问题可以应用于各种实际场景,比如在资源分配、决策分析和算法设计中。 动态规划方法...

    C 代码 寻求子集和问题的解,其中需要 查找具有给定总和的整数子集.rar

    这个问题通常被表述为:给定一个整数数组,找出所有可能的子集,这些子集的元素之和等于给定的目标值。在这个场景中,我们有两个文件,`subset_sum` 和 `subset_sum_test`,它们分别代表了该问题的解决方案和测试...

    1122 子集和数问题

    该问题的目标是从一个给定的集合中找出若干个元素,使得这些元素的总和恰好等于一个给定的目标值。由于涉及到元素的选择与组合,解决这一问题通常需要采用回溯法进行试探性搜索,这种方法是递归或迭代方式的实现。 ...

    leetcode2-Data-Structures-and-Algorithms:一些流行算法的CPP代码

    nums,找出其总和最大的连续子数组(至少包含一个数字)并返回其总和。 给定一组区间,合并所有重叠的区间。 输入:区间 = [[1,3],[2,6],[8,10],[15,18]]输出: [[1,6],[8,10],[15,18]]解释:由于区间 [1,3] 和 [2,6...

    Leetcode 5个经典元素和问题题解_leetcode_leetcode题解_

    问题要求在给定整数数组中找出两个数,使得它们的和等于一个特定的目标值。高效的解决方案是使用哈希表,先遍历数组,对于每个元素,我们检查哈希表中是否存在目标值减去该元素的值,如果存在则返回这两个数,否则将...

    _leetcode-python.pdf

    - Maximum Subarray: 寻找一个整数数组中,连续子数组的最大和。 - Spiral Matrix: 给定一个m×n矩阵,以螺旋方式遍历矩阵中的所有元素一次,并且只遍历一次。 - Merge Intervals: 给定一组区间,请合并所有重叠的...

    前端大厂最新面试题-bit-manipulation.docx

    在数字操作中,数字转换为十六进制数是一个常见的问题。我们可以使用位运算来解决这个问题。 15. 两整数之和 在数学中,两整数之和是一个常见的问题。我们可以使用位运算来解决这个问题。 16. 整数替换 在数字...

    Leetcode题目+解析+思路+答案.pdf

    - **Plus One**:给定一个整数数组,将其加一。 - **Pascal's Triangle**:生成帕斯卡三角形的某一行。 - **Merge Sorted Array**:合并两个已排序的数组,使合并后的数组仍然有序。 - **Sum**:计算数组的总和...

    离散数学2习题选解1

    - 教材P142T25: 对于一个有n个元素的集合S,计算存在多少个有序对(A,B),其中A和B都是S的子集且A包含在B中。解答涉及组合计数,指出对于任一基数为k的子集A,有2n-k个不同的B与A形成有序对,总和由二项式定理计算...

    匹配总和

    如果我们要找到数组中是否存在一个子集,其元素之和等于给定的目标值,可以创建一个二维数组dp,其中dp[i][j]表示在数组的前i个元素中是否有可能选出一个和为j的子集。通过递推公式,我们可以逐步构建这个数组,从而...

    leetcode中国-Data_Structures-Algorithms:待补充!!

    在整数数组上查找总和等于给定数字的所有对 在 3 个排序数组中找到公共元素 用 O(1) 额外空间在交替的正负项中重新排列数组 查找是否存在总和等于 0 的子数组 求大数的阶乘 找到最大乘积子数组 找到最长的连续子序列...

    ACM/ICPC常用算法的代码库(吉林大学版,强烈推荐)

    - **所有数位相加**:计算一个整数中所有数字的总和。 #### Number数论 - **递推求欧拉函数PHI(I)**:计算欧拉函数φ(i),即小于i且与i互质的正整数的数量。 - **单独求欧拉函数PHI(X)**:计算欧拉函数φ(x)的具体...

    数学奥林匹克辅导丛书-算两次.pdf

    **题目**:设\(S\)为正整数\(n\)的所有非空子集的集合。对于\(S\)中的每个子集\(T\),定义其权重为\(T\)中最大元素与最小元素之差。求所有这些权重之和。 **解法一**(直接法):直接计算每个子集中最大元素与最小...

    《面向对象程序设计基础》习题解答.doc

    要判断一个整数m是否为完全数,我们可以通过一个简单的算法:从2遍历到m-1,检查每个数a是否能够整除m,如果可以整除,则a是m的一个因子,将其累加到一个总和sum中。遍历完成后,如果sum等于m,那么m就是一个完全数...

    偶数子总和问题:DP-2

    "偶数子总和问题"是一个典型的子集和问题变种,其目标是从给定的一组整数中找出所有可能的子集,使得这些子集的元素之和为偶数。此问题的关键在于利用动态规划的状态转移方程来避免重复计算,提高效率。 动态规划的...

    二级C上机精选程序题

    这个问题需要统计所有正整数的个数,以及这些数的各位数字之和为奇数的个数,同时计算这两个子集的平均值。这需要用到循环、条件判断、累加求和以及除法运算。 5. **求π的值**: 使用数值方法(如级数展开或牛顿...

    算法与数据结构 算法分析课程 第9章 NP完全性理论与近似算法 共36页.pptx

    - **顶点覆盖问题**:目标是在图中找出最小顶点集合,使得图中的每条边至少有一个端点在这个集合中。 - **旅行售货员问题**(TSP):寻找一条最短路径,该路径访问每个城市恰好一次,并最终返回起点。 - **集合覆盖...

    ACM-ICPC代码库.吉林大学2007-2008

    24. **所有数位相加**:计算一个数字中所有数位的总和。 #### 数论(Number Theory) 1. **递推求欧拉函数PHI(I)**和**单独求欧拉函数PHI(X)**:欧拉函数φ(n)计算小于等于n的正整数中与n互质的数的数量。 2. **...

    用C#语言解决的半数集问题(带整个结果的输出)

    半数集问题是一个在计算机科学领域中常见的算法挑战,它要求找出一个集合中元素的一半,使得这半部分元素的和等于另一半元素的和。这个问题通常用于考察编程者对数组处理、排序、查找以及数学思维的能力。在这个场景...

Global site tag (gtag.js) - Google Analytics