Solution 21: 子集和问题

问题描述

输入两个整数n和m,从数列1,2,3,...,n中随意取出几个数。

使其和等于m,把所有符合的组合列出来。

解决思路

dfs,注意:

1. 一个元素只能使用一次;

2. 保证输出的集合不重复。

程序

public class SubsetSum {
	public List<List<Integer>> getSubset(int n, int m) {
		List<List<Integer>> res = new ArrayList<List<Integer>>();

		if (n <= 0 || m <= 0 || m > n * (n + 1) / 2) {
			return res;
		}

		int[] nums = new int[n];
		for (int i = 0; i < nums.length; i++) {
			nums[i] = i + 1;
		}

		List<Integer> sol = new ArrayList<Integer>();
		helper(res, sol, nums, m, 0);
		return res;
	}

	private void helper(List<List<Integer>> res, List<Integer> sol, int[] nums, int m, int start) {
		if (m < 0) {
			return ;
		}
		if (m == 0) {
			res.add(new ArrayList<Integer>(sol));
			return;
		}

		for (int i = start; i < nums.length; i++) {
			if (sol.contains(nums[i])) {
				continue;
			}
			sol.add(nums[i]);
			helper(res, sol, nums, m - nums[i], i + 1);
			sol.remove(sol.size() - 1);
		}
	}
}

  

时间: 2024-12-03 12:21:19

Solution 21: 子集和问题的相关文章

剑指offer 1

1 class Solution { 2 public: 3 bool Find(int target, vector<vector<int> > array) { 4 int s1 = array.size(), s2 = array[0].size(); 5 int i = s1 - 1, j = 0; 6 while (i >= 0 && j < s2) { 7 if (array[i][j] == target) { 8 return true;

剑指offer 1-6

1. 二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 分析: 从左下角(或右上角)开始判断与要查找元素的大小,小于则向右走,大于则向上走.(类似与减而治之的思想,一次去掉一行或一列). 时间复杂度O(m + n) 代码: 1 class Solution { 2 public: 3 bool Find(int target, vector<vector<in

【string】hash table, two pointers, string

利用hash table, two pointers, string的题目. 1.求最长不重复子串的长度 hash table体现在一个数组,下标是字符串中元素的ASCII值,下标对应的元素代表该元素在字符串中出现的位置. two pointers体现在用i一步步向前移去遍历字符串中的元素,作为不重复子串的末尾位置:用j指向不重复字符区间的首字符的位置. 1 /*************************** 2 @date 4.23 3 @description https://leet

[容易]插入区间

题目来源:http://www.lintcode.com/zh-cn/problem/insert-interval/ 可以accept的程序如下: 1 /** 2 * Definition of Interval: 3 * class Interval { 4 * public: 5 * int start, end; 6 * Interval(int start, int end) { 7 * this->start = start; 8 * this->end = end; 9 * }

【软件编译】vs2013下编译notepad++源码

1 下载notepad++源码 登录notepad++官网https://notepad-plus-plus.org/ 2 对scintilla进行编译,获得SciLexer.dll文件    具体编译方法请自行谷歌,本人赶时间,直接从已安装的notepad++中复制了一份. problem 1:如果没有这个文件会在一开始报错 problem 2:如果这个文件是自己编译获得的,则这个文件没有签名,也会报错. solution 2-1:只需要将验证签名的函数去掉或强行通过验证就可以了.(通过在整个

二维数组查询算法

题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 实现思路:由于行列都为递增排序,所以可以从左下角开始比较查询,若目标值target大于该数,则将查询位置右移,否则上移,即可达到查询目的. 代码: 1 #_*_coding:utf-8_*_ 2 3 class Solution: 4 # array 二维列表 5 def Find(self, target, array):

二叉树题目总结(一)

1. 线索化二叉树 一颗有n个节点的二叉树,必然有n + 1个空指针,可以利用这些空指针记录二叉树的某种遍历序的前驱和(或)后继信息 下面给出中序线索化二叉树的代码: 1 #include <iostream> 2 3 struct ThreadTreeNode { 4 int val; 5 bool ltag; /* 0 for link, 1 for thread */ 6 bool rtag; 7 ThreadTreeNode *left; 8 ThreadTreeNode *right

leetcode算法:Two Sum II - Input array is sorted

Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 m

51nod 1116:K进制下的大数

51nod 1116:K进制下的大数 题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1116 题目大意:给定一个大数,该数在$K$进制下是$K-1$的倍数,问最小的$K$($2 \leqslant K \leqslant 36$)是多少,若无解输出No Solution. 二项式定理 这题虽然可以暴力枚举,但还有更优雅的做法. 考虑一个$K$进制的大数$A$可以被表示为$\sum_{x=0}a_xK^x$,