9.9递归和动态规划(四)——返回某集合的所有子集

/**

* 功能:返回某集合的所有子集。

*/

三种方法:

方法一:迭代

	//迭代
	/**
	 * 注意:每次加入集合后会改变原来的集合,无法继续从集合中取出元素。
	 * 		必须通过一个中间参数moreSubsets来保存中间结果,最后加入allSubsets。
	 * @author Lynne
	 * @param set
	 * @param index
	 * @return
	 */
	public static ArrayList<ArrayList<Integer>> getSubsets2(ArrayList<Integer> set,int index){
		ArrayList<ArrayList<Integer>> allSubsets=new ArrayList<ArrayList<Integer>>();

		allSubsets.add(new ArrayList<Integer> ());//加入空集合

		while(index<set.size()){
			int item=set.get(index);
			ArrayList<ArrayList<Integer>> moreSubsets=new ArrayList<ArrayList<Integer>>();	

			for(ArrayList<Integer> subsets:allSubsets){
				ArrayList<Integer> newSubsets=new ArrayList<Integer>();
				newSubsets.addAll(subsets);
				newSubsets.add(item);
				moreSubsets.add(newSubsets);
			}
			allSubsets.addAll(moreSubsets);
			index++;
		}
		return allSubsets;
	}

方法二:递归

	//递归法
	/**
	 * 思路:简单构造法
	 * 		计算P(n-1),复制一份结果,然后在每个复制后的集合中加入an。
	 * @param set
	 * @param index
	 * @return
	 */
	public static ArrayList<ArrayList<Integer>> getSubsets(ArrayList<Integer> set,int index){
		ArrayList<ArrayList<Integer>> allSubsets;

		if(set.size()==index){//终止条件,加入空集合
			allSubsets=new ArrayList<ArrayList<Integer>>();
			allSubsets.add(new ArrayList<Integer>());//空集合
		}else{
			allSubsets=getSubsets(set, index+1);
			int item=set.get(index);
			ArrayList<ArrayList<Integer>> moreSubsets=new ArrayList<ArrayList<Integer>>();	

			for(ArrayList<Integer> subsets:allSubsets){
				ArrayList<Integer> newSubsets=new ArrayList<Integer>();
				newSubsets.addAll(subsets);
				newSubsets.add(item);
				moreSubsets.add(newSubsets);
			}
			allSubsets.addAll(moreSubsets);
		}
		return allSubsets;
	}

方法三:组合数学

	//组合数学
	/**
	 * 思路:迭代访问1到2^n的所有数字,再转化为集合
	 * 每个元素有两个选择:1)在集合中(“yes”);2)不在集合中(“no”)。即每个子集都是一串yes和no。
	 * 总共有2^n个子集,将每个yes看做1,每个no看做0,即可以表示为一个二进制串。
	 * 所以,构造所有的子集就等同于构造所有的二进制数。迭代访问1到2^n的所有数字,再转化为集合。
	 * @param set
	 * @return
	 */
	public static ArrayList<ArrayList<Integer>> getSubsets(ArrayList<Integer> set){
		ArrayList<ArrayList<Integer>> allSubsets=new ArrayList<ArrayList<Integer>>();

		int size=1<<set.size();//集合的子集个数,计算2^n。
		for(int i=0;i<size;i++){
			ArrayList<Integer> subsets=new ArrayList<Integer>();
			subsets=convertIntToSet(i);
			allSubsets.add(subsets);
		}

		return allSubsets;
	}

	public static ArrayList<Integer> convertIntToSet(int x){
		ArrayList<Integer> subsets=new ArrayList<Integer>();
		for(int i=x;i>=1;i>>=1){
			if((i&1)==1)
				subsets.add(i);
		}
		return subsets;
	}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 13:08:46

9.9递归和动态规划(四)——返回某集合的所有子集的相关文章

9.9递归和动态规划(四)——返回某集合的全部子集

/** * 功能:返回某集合的全部子集. */ 三种方法: 方法一:迭代 //迭代 /** * 注意:每次增加集合后会改变原来的集合,无法继续从集合中取出元素. * 必须通过一个中间參数moreSubsets来保存中间结果,最后增加allSubsets. * @author Lynne * @param set * @param index * @return */ public static ArrayList<ArrayList<Integer>> getSubsets2(Ar

编写一个方法,返回某集合的所有子集

ArrayList<ArrayList<Integer>> getSubsets(ArrayList<Integer> set,int index) { ArrayList<ArrayList<Integer>> allsubsets; if(set.size()==index)//终止条件,加入空集合 { allsubsets= new ArrayList<ArrayList<Integer>>(); allsubset

算法初级面试题08——递归和动态规划的精髓、阶乘、汉诺塔、子序列和全排列、母牛问题、逆序栈、最小的路径和、数组累加成指定整数、背包问题

第八课主要介绍递归和动态规划 介绍递归和动态规划 暴力递归: 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续进行递归的条件(base case) 3,有当得到了子问题的结果之后的决策过程 4,不记录每一个子问题的解 动态规划 1,从暴力递归中来 2,将每一个子问题的解记录下来,避免重复计算 3,把暴力递归的过程,抽象成了状态表达 4,并且存在化简状态表达,使其更加简洁的可能 图灵引入的是:我不知道怎么算,但是我知道怎么试.知道怎么暴力破解出来. 要学会,练习懂得怎么尝试.

左神算法第八节课:介绍递归和动态规划(汉诺塔问题;打印字符串的全部子序列含空;打印字符串的全排列,无重复排列;母牛数量;递归栈;数组的最小路径和;数组累加和问题,一定条件下最大值问题(01背包))

暴力递归: 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续进行递归的条件(base case) 3,有当得到了子问题的结果之后的决策过程 4,不记录每一个子问题的解 动态规划 1,从暴力递归中来 2,将每一个子问题的解记录下来,避免重复计算 3,把暴力递归的过程,抽象成了状态表达 4,并且存在化简状态表达,使其更加简洁的可能 一:递归 1. 汉诺塔问题 汉诺塔问题(不能大压小,只能小压大),打印n层汉诺塔从最左边移动到最右边的全部过程. 左中右另称为 from.to.hel

【动态规划专题】1:斐波拉契数列问题的递归和动态规划

<程序员代码面试指南--IT名企算法与数据结构题目最优解> 左程云 著 斐波拉契数列问题的递归和动态规划 [题目]:给定整数N,返回斐波拉契数列的第N项.补充问题1:给定整数N,代表台阶数,一次可以跨2个或者1个台阶,返回有多少种走法.补充问题2:假设农场中成熟的母牛每年只会生产1头小母牛,并且永远不会死.第一年农场只有1只成熟的母牛,从第2年开始,母牛开始生产小母牛.每只小母牛3年后成熟又可以生产小母牛.给定整数N,求出N年后牛的数量. [举例]斐波拉契数列f(0)=0, f(1)=1,f(

70. Climbing Stairs【leetcode】递归,动态规划,java,算法

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? Note: Given n will be a positive integer. 题目分析:每次只能走1或2步,问n步的话有多少中走法???? 可以用动态规划和递归解

斐波那契数列的实现(简单递归和动态规划)

斐波那契数列的实现(简单递归和动态规划) 一.简单递归的实现 1 #include "stdafx.h" 2 #include <string> 3 using namespace std; 4 int f(int n) 5 { 6 if (n == 0) 7 { 8 return 0; 9 } 10 if (n == 1) 11 { 12 return 1; 13 } 14 return f(n - 1) + f(n - 2); 15 } 16 int _tmain(in

利用递归和动态规划来求解组合数

组合数定义:从m个不同元素中,任取n(n≤m)个元素并成一组,叫做从m个不同元素中取出n个元素的一个组合:从m个不同元素中取出n(n≤m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数. 下面是一种比较通俗的计算公式: 其递归公式为: c(n,m)=c(n-1,m-1)+c(n-1,m) 下面是c++实现该递归算法: #include <iostream> #include <stdlib.h> #define EXIT -1 using namespace st

java集合(四)Set集合之HashMap详解

一.概要 第1部分 概要 第2部分 HashMap介绍 第3部分 HashMap数据结构第4部分 HashMap源码解析(基于JDK1.6.0_45)    第4.1部分 HashMap的“拉链法”相关内容    第4.2部分 HashMap的构造函数    第4.3部分 HashMap的主要对外接口    第4.4部分 HashMap实现的Cloneable接口    第4.5部分 HashMap实现的Serializable接口第5部分 HashMap遍历方式第6部分 HashMap示例 二