- 数据结构与算法
- 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
广告