题目

地址:https://leetcode.com/problems/subsets/

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[]
]

1. DFS深度优先回溯解法

思路解析:

  1. 遍历数组中的元素,要么选择,要么不选择。
  2. 注意退出条件即可if (nums == null || index == nums.length) 。表示可能数组为空,可能index已经越界,则添加到结果列表中。
package backtracking;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;// https://leetcode.com/problems/subsets/
public class Subsets {public static void main(String[] args) {int[] nums = new int[]{1,2,3};Subsets obj = new Subsets();List<List<Integer>> resultList = obj.subsets(nums);System.out.println(Arrays.toString(resultList.toArray()));}public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> resultList = new ArrayList<List<Integer>>();// dfsdfs(nums, resultList, new ArrayList<Integer>(), 0);return resultList;}private void dfs(int[] nums, List<List<Integer>> resultList, List<Integer> list, int index) {// exitif (nums == null || index == nums.length) {resultList.add(new ArrayList<Integer>(list));return;}// add itemlist.add(nums[index]);dfs(nums, resultList, list, index + 1);// not add itemlist.remove(list.size() - 1);dfs(nums, resultList, list, index + 1);}
}

2. 遍历执行

从一个空列表List<List<Integer>> outputList开始,添加一个空列表new ArrayList<Integer>(),遍历所有数据(比如:{1, 2, 3}),

  1. 新建一个空列表List<List<Integer>> newList,
  2. 遍历列表List<List<Integer>> outputList,把已有子项都添加上新的数字,
比如遍历到1,
[ ] > [1]
比如遍历到2,
[ ] > [2]
[1] > [1, 2]
  1. 遍历列表new ArrayList<Integer>(),把新生成的子列表追加到已有列表的后面List<List<Integer>> outputList
public List<List<Integer>> subsetsWithRecursion(int[] nums) {List<List<Integer>> outputList = new ArrayList<List<Integer>>();outputList.add(new ArrayList<Integer>());for (int num: nums) {List<List<Integer>> newList = new ArrayList<List<Integer>>();for (List<Integer> list: outputList) {newList.add(new ArrayList<Integer>(list) {{ add(num); }});}for (List<Integer> list: newList) {outputList.add(list);}}return outputList;
}

3. 回溯解法,达到指定长度就返回

public List<List<Integer>> subsetsWithBacktrack(int[] nums) {List<List<Integer>> resultList = new ArrayList<List<Integer>>();for (int len = 0; len <= nums.length; len++) {// backtrackbacktrack(nums, resultList, new ArrayList<Integer>(), 0, len);}return resultList;
}private void backtrack(int[] nums, List<List<Integer>> resultList, List<Integer> list, int first, int len) {// exitif (list.size() == len) {resultList.add(new ArrayList<Integer>(list));return;}if (first == nums.length) {return;}list.add(nums[first]);backtrack(nums, resultList, list, first + 1, len);list.remove(list.size() - 1);backtrack(nums, resultList, list, first + 1, len);
}

4. 二进制位组装

算法思想来自 Donald E.Knuth. 组装成跟数组长度一样的二进制,如果为1则添加进来,否则就不添加。

public List<List<Integer>> subsetsWithBinarySorted(int[] nums) {List<List<Integer>> resultList = new ArrayList<List<Integer>>();int n = nums.length;for (int i = (int)Math.pow(2, n); i < (int)Math.pow(2, n + 1); i++) {// generate bitmask, from 0..00 to 1..11String bitmask = Integer.toBinaryString(i).substring(1);// append subset corresponding to that bitmaskList<Integer> list = new ArrayList<Integer>();for (int k = 0; k < n; k++) {if (bitmask.charAt(k) == '1') {list.add(nums[k]);}}resultList.add(list);}return resultList;}

代码下载

https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/backtracking/Subsets.java

参考

https://leetcode.com/problems/subsets/solution/

https://www-cs-faculty.stanford.edu/~knuth/taocp.html

算法:回溯十一 Subsets数组的子数组集合4种解法相关推荐

  1. 编程之美-2.14-求数组的子数组之和的最大值

    这个以前写过,见求数组的最长子数组之和的最大值 这里说一下后面扩展题目. 1. 简述 1) 如果数组首尾相连,即允许找到一组数字(A[i],···,A[n-1], A[0],···, A[j]),请使 ...

  2. 二位数组的子数组最大值

    该题是poj的1050号题:http://poj.org/problem?id=1050 同时在<编程之美> 2.15 小节 思想是: 1.把二维降到一维,把 同一列的若干个数的和算出来, ...

  3. 【C】课堂结对联系-求整数数组的子数组之和的最大值(党云龙、黄为)

    测试题目 求整数数组的子数组之和的最大值. 题目分析 首先是明确题目的目的:求最大值:其次是考虑子数组求和.这里将求最大值写成一个单独的函数.主函数未测试函数.这里用到了二重循环,时间复杂度为N^2. ...

  4. 算法-求数组的子数组之和的最大值

    一个一维int数组,这个数组有很多子数组,那么子数组之和的最大值是什么呢? 思考 1.题目说的子数组是连续的: 2.题目只需要求和,并不需要返回子数组的具体位置: 3.数组的元素是整数,所以数组可能包 ...

  5. 三种算法求解一个数组的子数组最大和

    题目:要求一个数组连续下标和的最大值,数组的元素可正.可负.可为零,例如-2,5,3,-6,4,-8,6将返回8. 这题是很经典的一道面试题,也有各种解法,从算法分析上,时间复杂度也有很大差别,下面我 ...

  6. 求数组的子数组之和的最大值

    一个有N个整数元素的一维数组( A[0], A[1], ... , A[n-2], A[n-1]),子数组之和的最大值是什么?(要求子数组的元素是连续的) 例子:有数组( -2, 5, 3, -6, ...

  7. 【Java基础[数组及对象数组取子数组]】

    public static void main1(String[] args) {int[] arr = new int[8];// 经典for循环, 用于给数组赋值或其他和下标相关的操作for (i ...

  8. Algorithm One Day One--求输入的数组其子数组的最大值

    算法是编程的灵魂,是编程思想的精髓----Algorithm One Day One /******************************************************** ...

  9. 编程之美2.14 求数组的子数组之和的最大值

          这是一个在面试中出现概率很高的一道题目,就拿我来说吧,面试了5家公司中,两家公司问了这道题目,可见,这道题目是非常经典的.       解题思想也不是很难,我熟悉的有:两种解题办法:   ...

  10. leetcode算法题--删除一次得到子数组最大和★

    原题链接:https://leetcode-cn.com/problems/maximum-subarray-sum-with-one-deletion/ 1.穷举(超时) dp[i][j]表示arr ...

最新文章

  1. Mindmanager 甘特图杠上Mindmanager 鱼骨图
  2. ROS学习(五):package.xml 文件
  3. (转)flex中使用swc实现更好的界面代码分离
  4. Java内存区域(运行时数据区域)和内存模型(JMM)
  5. linux数据包注释,关于 linux中TCP数据包(SKB)序列号的小笔记
  6. 给超链接(a标签)加onclick事件
  7. java日历类add方法_Java日历setMinimalDaysInFirstWeek()方法与示例
  8. java微信内h5调起支付_java微信支付--------公众号内H5调起支付
  9. 卢伟冰:Redmi K30 Pro的主板可能是业内最复杂“三明治”主板设计
  10. Echarts鼠标悬浮样式
  11. C# sqlDataReader区别Dataset
  12. Maven依赖冲突避坑指北
  13. 前端网络基础-传输层UDP协议
  14. android 短信超链接,Android处理网页的短信链接
  15. ios wifi 定位_一种IOS设备的集中式Wifi室内定位方法
  16. 多级下料问题的建模--中英文翻译
  17. 量子计算机能超越光速,量子纠缠: 真的可以“超越光速”吗?
  18. Linux下C语言实现多线程排序文件内容
  19. 初探USB3.0极简方案FT601Q芯片方案
  20. 量化投资常用技能——绘图篇 1:绘制股票收盘价格曲线和ochl烛状图

热门文章

  1. c++ascii表_几道和散列(哈希)表有关的面试题
  2. [转]跨域资源共享 CORS 详解
  3. 1024程序员 | 我如何从零基础转行成为一个自信的前端
  4. 淘富成真,硬件智能—— 硬件创新一站赋能平台
  5. Linux下出现command not found的解决办法
  6. UITextField的leftView
  7. 【转载】C# 中的各种命名规范
  8. JBuilder 2005 Enterprise注册破解
  9. 谁会成为中国互联网下一代英雄
  10. STC学习:红外通信1(收发单个字节)