LeetCode_OJ【78】Subsets
2016-04-27 16:21
381 查看
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 =
Subscribe to see which companies asked this question
返回一个集合的所有子集,子集中所有元素按顺序排列。
这个题第一反应就是用回溯,思路比较常规,性能也不错,这里就不介绍了,下面是JAVA实现:
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> path = new ArrayList<Integer>();
List<Integer> rem = new ArrayList<Integer>();
for(int i = 0 ; i < nums.length ; i++)
rem.add(nums[i]);
Collections.sort(rem);
generate(res,path,rem,0);
return res;
}
public void generate(List<List<Integer>> res,List<Integer> path,List<Integer> rem, int k){
res.add(new ArrayList<Integer>(path));
if(k == rem.size())
return;
for(int i = k ; i < rem.size() ; i ++){
path.add(rem.get(i));
rem.remove(i);
generate(res,path,rem,i);
Integer last = path.remove(path.size() -1);
rem.add(i,last);
}
}
}
后来看到提示里面有 位操作,以前从来没碰到这种解法的题目,找了一些资料看了下,还是很受启发的。
nums里面有n个元素,那么有2^n个子集,用数字0 ~ (2^n-1) 分别表示这些子集,对于任意一个数字,如果其对应的2进制数中的第 i 位为1,则表示nums[i]包含在该数字对应的子集中。
这样可以直接通过循环一个一个将子集计算出来,效率比回溯要高一些。
下面是位操作的JAVA实现:
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
int max = 1 << nums.length;
Arrays.sort(nums);
for( ; max > 0 ; max --){
List<Integer> tmp = new ArrayList<Integer>();
for(int i = max -1,index = 0 ; i > 0 ; i = i >> 1,index ++){
if((i & 1) == 1)
tmp.add(nums[index]);
}
res.add(tmp);
}
return res;
}
}
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], [] ]
Subscribe to see which companies asked this question
返回一个集合的所有子集,子集中所有元素按顺序排列。
这个题第一反应就是用回溯,思路比较常规,性能也不错,这里就不介绍了,下面是JAVA实现:
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> path = new ArrayList<Integer>();
List<Integer> rem = new ArrayList<Integer>();
for(int i = 0 ; i < nums.length ; i++)
rem.add(nums[i]);
Collections.sort(rem);
generate(res,path,rem,0);
return res;
}
public void generate(List<List<Integer>> res,List<Integer> path,List<Integer> rem, int k){
res.add(new ArrayList<Integer>(path));
if(k == rem.size())
return;
for(int i = k ; i < rem.size() ; i ++){
path.add(rem.get(i));
rem.remove(i);
generate(res,path,rem,i);
Integer last = path.remove(path.size() -1);
rem.add(i,last);
}
}
}
后来看到提示里面有 位操作,以前从来没碰到这种解法的题目,找了一些资料看了下,还是很受启发的。
nums里面有n个元素,那么有2^n个子集,用数字0 ~ (2^n-1) 分别表示这些子集,对于任意一个数字,如果其对应的2进制数中的第 i 位为1,则表示nums[i]包含在该数字对应的子集中。
这样可以直接通过循环一个一个将子集计算出来,效率比回溯要高一些。
下面是位操作的JAVA实现:
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
int max = 1 << nums.length;
Arrays.sort(nums);
for( ; max > 0 ; max --){
List<Integer> tmp = new ArrayList<Integer>();
for(int i = max -1,index = 0 ; i > 0 ; i = i >> 1,index ++){
if((i & 1) == 1)
tmp.add(nums[index]);
}
res.add(tmp);
}
return res;
}
}
相关文章推荐
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C/C++位操作实例总结
- javascript数组操作总结和属性、方法介绍
- mysql_fetch_assoc和mysql_fetch_row的功能加起来就是mysql_fetch_array
- JavaScript Array扩展实现代码
- JavaScript之数组(Array)详解
- Javascript实现Array和String互转换的方法
- C#中Array与ArrayList用法及转换的方法
- Array栈方法和队列方法的特点说明
- Array.prototype.slice 使用扩展
- Array, Array Constructor, for in loop, typeof, instanceOf
- 实例详解ECMAScript5中新增的Array方法
- Javascript数组Array基础介绍
- js Array的用法总结
- JavaScript 判断判断某个对象是Object还是一个Array
- C++位操作的常见用法小结
- Javascript中的Array数组对象详谈
- js模拟实现Array的sort方法
- 在javascript将NodeList作为Array数组处理的方法
- PHP array_multisort()函数的使用札记