LeetCode OJ 78. Subsets
2016-06-03 09:26
218 查看
Given a set of distinct integers, nums, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.
For example,
If nums =
【题目分析】
这个题目是求一个集合的子集,要求子集中的元素不能降序排列,而且不含有重复的元素。
【思路】
求一个集合的所有子集我们可以考虑子集中包含集合的若干个元素,从0个到n(集合的大小)。如果含有0个元素,就是空集,含有一个元素的话就是把集合中每个元素取一次,含有两个元素的话就是找到集合中所有两个元素的组合......以此类推。
问题是这个过程该如何描述呢?假设我们要从一个增序排序的集合中选取所有两个元素的组合,从集合中开始选取一个之前没有选过的元素a,然后再从这个元素后面选择一个元素b。当我们开始找下一个组合时,需要回溯到当前组合,删除元组中的第二个元素b,然后继续向后寻找。同样当我们找到所有第一个元素为a的所有二元子集时,我们需要删除a,然后在a后面找到下一个二元组的开始元素a2,然后继续上面的过程。因此这个过程是一个递归回溯的过程。
回溯法
回溯法按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如果不可行,则跳过对该节点为根的子树的搜索,逐层向其祖先节点回溯;否则,进入该子树,继续按深度优先策略搜索。
回溯法的基本行为是搜索,搜索过程使用剪枝函数来为了避免无效的搜索。剪枝函数包括两类:1. 使用约束函数,剪去不满足约束条件的路径;2.使用限界函数,剪去不能得到最优解的路径。
问题的关键在于如何定义问题的解空间,转化成树(即解空间树)。解空间树分为两种:子集树和排列树。两种在算法结构和思路上大体相同。
【java代码】
Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.
For example,
If nums =
[1,2,3], a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
【题目分析】
这个题目是求一个集合的子集,要求子集中的元素不能降序排列,而且不含有重复的元素。
【思路】
求一个集合的所有子集我们可以考虑子集中包含集合的若干个元素,从0个到n(集合的大小)。如果含有0个元素,就是空集,含有一个元素的话就是把集合中每个元素取一次,含有两个元素的话就是找到集合中所有两个元素的组合......以此类推。
问题是这个过程该如何描述呢?假设我们要从一个增序排序的集合中选取所有两个元素的组合,从集合中开始选取一个之前没有选过的元素a,然后再从这个元素后面选择一个元素b。当我们开始找下一个组合时,需要回溯到当前组合,删除元组中的第二个元素b,然后继续向后寻找。同样当我们找到所有第一个元素为a的所有二元子集时,我们需要删除a,然后在a后面找到下一个二元组的开始元素a2,然后继续上面的过程。因此这个过程是一个递归回溯的过程。
回溯法
回溯法按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如果不可行,则跳过对该节点为根的子树的搜索,逐层向其祖先节点回溯;否则,进入该子树,继续按深度优先策略搜索。
回溯法的基本行为是搜索,搜索过程使用剪枝函数来为了避免无效的搜索。剪枝函数包括两类:1. 使用约束函数,剪去不满足约束条件的路径;2.使用限界函数,剪去不能得到最优解的路径。
问题的关键在于如何定义问题的解空间,转化成树(即解空间树)。解空间树分为两种:子集树和排列树。两种在算法结构和思路上大体相同。
【java代码】
public class Solution { public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> list = new ArrayList<>(); List<Integer> clist = new ArrayList<>(); list.add(clist); if(nums == null) return list; Arrays.sort(nums); for(int i = 1; i <= nums.length; i++){ clist.clear(); DFS(nums, 0, i, clist, list); } return list; } public void DFS(int[] nums, int start, int number, List<Integer> clist, List<List<Integer>> list){ if(number == clist.size()){ list.add(new ArrayList<>(clist)); return; } for(int i = start;i < nums.length; i++) { clist.add(nums[i]); DFS(nums, i+1, number, clist, list); clist.remove(clist.size()-1); } } }
public class Solution { public List<List<Integer>> subsets(int[] nums) { Arrays.sort(nums); List<List<Integer>> ret = new ArrayList<>(); dfs(nums, 0, new ArrayList<>(), ret); return ret; } private void dfs(int[] nums, int idx, List<Integer> path, List<List<Integer>> ret) { ret.add(path); for (int i = idx; i < nums.length; i++) { List<Integer> p = new ArrayList<>(path); p.add(nums[i]); dfs(nums, i+1, p, ret); } } }
相关文章推荐
- 注解框架ButterKnife
- 无法访问windows installer服务
- SpringMVC整合MongoDB开发 高级操作
- 关于java数组中某个元素用等号赋值给中间变量需要注意的问题。
- 26. Remove Duplicates from Sorted Array [easy]
- 【Android Studio快捷键】如何设置代码自动提示
- ASP.NET中控件的EnableViewState属性及彻底禁用
- 第七天 抽屉菜单(性能优化版)
- c#事件(2)之相关内容
- SpringMVC整合MongoDB开发 架构搭建
- 详解iOS应用中播放本地视频以及选取本地音频的组件用法
- JavaScript中getYear()显示错误问题!
- Iterator中next和hasnext的区别
- c#的事件(1)之基本语法
- 关于SQLException:Value'0000-00-00 00:00:00'can not be represented as java.sql.Timestamp的问题
- 第58课:使用Java和Scala在IDE中开发DataFrame实战学习笔记
- 【Java基础二】break && continue
- CAVLC算法解析
- 第六天 iOS中用Storyboard modal UINavigationController不能dismiss的问题
- 浅谈JavaScript的push(),pop(),concat()方法