- 数据结构与算法
- DSA - 首页
- DSA - 概述
- DSA - 环境搭建
- DSA - 算法基础
- DSA - 渐进分析
- 数据结构
- DSA - 数据结构基础
- DSA - 数据结构和类型
- DSA - 数组数据结构
- 链表
- DSA - 链表数据结构
- DSA - 双向链表数据结构
- DSA - 循环链表数据结构
- 栈与队列
- DSA - 栈数据结构
- DSA - 表达式解析
- DSA - 队列数据结构
- 搜索算法
- DSA - 搜索算法
- DSA - 线性搜索算法
- DSA - 二分搜索算法
- DSA - 插值搜索
- DSA - 跳跃搜索算法
- DSA - 指数搜索
- DSA - 斐波那契搜索
- DSA - 子列表搜索
- DSA - 哈希表
- 排序算法
- DSA - 排序算法
- DSA - 冒泡排序算法
- DSA - 插入排序算法
- DSA - 选择排序算法
- DSA - 归并排序算法
- DSA - 希尔排序算法
- DSA - 堆排序
- DSA - 桶排序算法
- DSA - 计数排序算法
- DSA - 基数排序算法
- DSA - 快速排序算法
- 图数据结构
- DSA - 图数据结构
- DSA - 深度优先遍历
- DSA - 广度优先遍历
- DSA - 生成树
- 树数据结构
- DSA - 树数据结构
- DSA - 树的遍历
- DSA - 二叉搜索树
- DSA - AVL树
- DSA - 红黑树
- DSA - B树
- DSA - B+树
- DSA - 伸展树
- DSA - 字典树
- DSA - 堆数据结构
- 递归
- DSA - 递归算法
- DSA - 使用递归解决汉诺塔问题
- DSA - 使用递归求斐波那契数列
- 分治法
- DSA - 分治法
- DSA - 最大最小问题
- DSA - Strassen矩阵乘法
- DSA - Karatsuba算法
- 贪心算法
- DSA - 贪心算法
- DSA - 旅行商问题(贪心算法)
- DSA - Prim最小生成树
- DSA - Kruskal最小生成树
- DSA - Dijkstra最短路径算法
- DSA - 地图着色算法
- DSA - 分数背包问题
- DSA - 带截止日期的作业排序
- DSA - 最佳合并模式算法
- 动态规划
- DSA - 动态规划
- DSA - 矩阵链乘法
- DSA - Floyd-Warshall算法
- DSA - 0-1背包问题
- DSA - 最长公共子序列算法
- DSA - 旅行商问题(动态规划)
- 近似算法
- DSA - 近似算法
- DSA - 顶点覆盖算法
- DSA - 集合覆盖问题
- DSA - 旅行商问题(近似算法)
- 随机化算法
- DSA - 随机化算法
- DSA - 随机化快速排序算法
- DSA - Karger最小割算法
- DSA - Fisher-Yates洗牌算法
- DSA有用资源
- DSA - 问答
- DSA - 快速指南
- DSA - 有用资源
- DSA - 讨论
子集和问题
子集和问题
在**子集和问题**中,给定一个包含一些非负整数元素的集合。同时还提供一个和值,我们的任务是找到给定集合的所有可能的子集,其元素之和与给定的和值相同。
**集合:**在数学术语中,**集合**被定义为相似类型对象的集合。集合的实体或对象必须通过相同的规则相互关联。
**子集:**假设有两个集合,即集合P和集合Q。当且仅当集合P的所有元素也属于集合Q时,集合P被称为集合Q的子集,反之则不一定成立。
输入输出场景
假设给定的集合和和值如下:
Set = {1, 9, 7, 5, 18, 12, 20, 15}
sum value = 35
给定集合的所有可能的子集,其中每个子集的每个元素的和与给定的和值相同,如下所示:
{1 9 7 18}
{1 9 5 20}
{5 18 12}
回溯法解决子集和问题
在解决子集和问题的朴素方法中,算法生成所有可能的排列,然后逐个检查有效解。每当一个解满足约束条件时,将其标记为解的一部分。
在解决子集和问题时,回溯法用于选择有效的子集。当一个项目无效时,我们将回溯以获取先前的子集,并添加另一个元素以获得解。
在最坏情况下,回溯法可能会生成所有组合,但是,通常情况下,它的性能优于朴素方法。
请按照以下步骤使用回溯法解决子集和问题:
首先,取一个空子集。
将下一个元素(索引为0)包含到空集中。
如果子集等于和值,则将其标记为解的一部分。
如果子集不是解并且小于和值,则向子集中添加下一个元素,直到找到有效的解。
现在,转到集合中的下一个元素并检查另一个解,直到所有组合都已尝试过。
示例
在本示例中,我们将说明如何在各种编程语言中解决子集和问题。
#include <stdio.h>
#define SIZE 7
void displaySubset(int subSet[], int size) {
for(int i = 0; i < size; i++) {
printf("%d ", subSet[i]);
}
printf("\n");
}
void subsetSum(int set[], int subSet[], int n, int subSize, int total, int nodeCount ,int sum) {
if( total == sum) {
//print the subset
displaySubset(subSet, subSize);
//for other subsets
if (subSize != 0)
subsetSum(set,subSet,n,subSize-2,total-set[nodeCount],nodeCount+1,sum);
return;
}else {
//find node along breadth
for( int i = nodeCount; i < n; i++ ) {
subSet[subSize] = set[i];
//do for next node in depth
subsetSum(set,subSet,n,subSize+1,total+set[i],i+1,sum);
}
}
}
void findSubset(int set[], int size, int sum) {
//create subset array to pass parameter of subsetSum
int subSet[size];
subsetSum(set, subSet, size, 0, 0, 0, sum);
}
int main() {
int weights[] = {1, 9, 7, 5, 18, 12, 20, 15};
int size = SIZE;
findSubset(weights, size, 35);
return 0;
}
#include <iostream>
using namespace std;
void displaySubset(int subSet[], int size) {
for(int i = 0; i < size; i++) {
cout << subSet[i] << " ";
}
cout << endl;
}
void subsetSum(int set[], int subSet[], int n, int subSize, int total, int nodeCount, int sum) {
if( total == sum) {
//print the subset
displaySubset(subSet, subSize);
//for other subsets
subsetSum(set, subSet, n, subSize-1, total-set[nodeCount], nodeCount+1,sum);
return;
}else {
//find node along breadth
for( int i = nodeCount; i < n; i++ ) {
subSet[subSize] = set[i];
//do for next node in depth
subsetSum(set, subSet, n, subSize+1, total+set[i], i+1, sum);
}
}
}
void findSubset(int set[], int size, int sum) {
//create subset array to pass parameter of subsetSum
int *subSet = new int[size];
subsetSum(set, subSet, size, 0, 0, 0, sum);
delete[] subSet;
}
int main() {
int weights[] = {1, 9, 7, 5, 18, 12, 20, 15};
int size = 7;
findSubset(weights, size, 35);
}
public class Main {
static void displaySubset(int subSet[], int size) {
for(int i = 0; i < size; i++) {
System.out.print(subSet[i] + " ");
}
System.out.println();
}
static void subsetSum(int set[], int subSet[], int n, int subSize, int total, int nodeCount ,int sum) {
if( total == sum) {
//print the subset
displaySubset(subSet, subSize);
//for other subsets
if (subSize != 0)
subsetSum(set,subSet,n,subSize-1,total-set[nodeCount],nodeCount+1,sum);
return;
} else {
//find node along breadth
for( int i = nodeCount; i < n; i++ ) {
subSet[subSize] = set[i];
//do for next node in depth
subsetSum(set,subSet,n,subSize+1,total+set[i],i+1,sum);
}
}
}
static void findSubset(int set[], int size, int sum) {
//create subset array to pass parameter of subsetSum
int subSet[] = new int[size];
subsetSum(set, subSet, size, 0, 0, 0, sum);
}
public static void main(String[] args) {
int weights[] = {1, 9, 7, 5, 18, 12, 20, 15};
int size = 7;
findSubset(weights, size, 35);
}
}
def displaySubset(subSet, size):
for i in range(size):
print(subSet[i], end=" ")
print()
def subsetSum(set, subSet, n, subSize, total, nodeCount, sum):
if total == sum:
#print the subset
displaySubset(subSet, subSize)
#for other subsets
if subSize != 0:
subsetSum(set, subSet, n, subSize-1, total-set[nodeCount], nodeCount+1, sum)
return
else:
#find node along breadth
for i in range(nodeCount, n):
subSet[subSize] = set[i]
#do for next node in depth
subsetSum(set, subSet, n, subSize+1, total+set[i], i+1, sum)
def findSubset(set, size, sum):
#create subset array to pass parameter of subsetSum
subSet = [0]*size
subsetSum(set, subSet, size, 0, 0, 0, sum)
if __name__ == "__main__":
weights = [1, 9, 7, 5, 18, 12, 20, 15]
size = 7
findSubset(weights, size, 35)
输出
1 9 7 18 1 9 5 20 5 18 12
广告