首页 > 其他分享 >打印数组的所有子集

打印数组的所有子集

时间:2022-10-02 16:34:10浏览次数:71  
标签:pre arr nums int 打印 子集 result 数组

打印数组的所有子集

作者:Grey

原文地址:

博客园:打印数组的所有子集

CSDN:打印数组的所有子集

无重复值情况

题目描述见: LeetCode 78. Subsets

主要思路

定义递归函数

void p(int[] arr, int i, LinkedList<Integer> pre, List<List<Integer>> result)

递归含义是:数组arri往后开始收集所有的子集,i之前生成的子集是pre,所有生成的子集都存在result中,

base case 就是,当i来到arr.length位置的时候,此时,已经没有选的字符了,将收集到的pre加入result中,

针对普遍情况,可能性有两种,第一种,不要选择i位置的元素,那么接下来直接调用p(arr, i + 1, pre, result)

第二种情况,选择i位置的元素,则将i位置的元素加入pre的下一个位置中,即:pre.addLast(arr[i]),然后去下一个位置做决策,即p(arr, i + 1, pre, result)

第二种情况中,不要忘记选择了i位置的元素,在后续决策完毕后,需要恢复现场,即pre.removeLast()

完整代码见

class Solution {
    public static List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        p(nums, 0, new LinkedList<>(), result);
        return result;
    }

    // i往后收集所有的子集
    public static void p(int[] arr, int i, LinkedList<Integer> pre, List<List<Integer>> result) {
        if (i == arr.length) {
            List<Integer> ans = new ArrayList<>(pre);
            result.add(ans);
        } else {
            // 不要i位置
            p(arr, i + 1, pre, result);
            pre.addLast(arr[i]);
            // 要i位置
            p(arr, i + 1, pre, result);
            // 恢复现场
            pre.removeLast();
        }
    }
}

有重复值情况

题目描述见: LeetCode 90. Subsets II

上一个问题由于题目限定了,没有重复元素,所以处理相对简单一些,本题说明了输入参数中可能会有重复的元素,且生成的子集不能有重复,此时有两个思路:

第一个思路,基于上一个问题的结果,即result,做去重操作,思路比较简单,但是复杂度会相对高一些,因为我们每次都要全量得到所有的子集,然后最后才去重。

第二个思路,在执行递归函数的时候,可以做一些剪枝,无须到最后再来去重,直接在递归函数中就把结果生成出来。接下来讲第二个解法的思路。

由于题目中已经说明,返回子集的顺序无要求,那么,我们可以首先将数组进行排序,排序后,所有相同的元素一定会排列到一起,然后定义一个和上一题一样的递归函数

void p(int[] nums, int i, LinkedList<Integer> pre, List<List<Integer>> result)

递归含义是:数组arri往后开始收集所有的无重复子集,i之前生成的子集是pre,所有生成的子集都存在result中。

接下来分析递归函数的可能性,我们可以不要选择i位置的元素,那么则可以直接加入result.add(new ArrayList<>(pre)),按上一题逻辑,接下来我们应该去i+1位置收集结果,但是,由于有重复元素,所以接下来ii+1,……i + n 都有可能是同一个元素,示例图如下

image

如上图,i一直到i+n都是元素a,直到i+n+1才是一个不同的元素,所以,当我们收集了i位置的元素以后,我们不能直接去i+1位置收集,而是应该从i+n+1位置开始收集。

完整代码见

class Solution {
    public static List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> lists = new ArrayList<>();
        Arrays.sort(nums);
        p(nums, 0, new LinkedList<>(), lists);
        return lists;
    }

    public static void p(int[] nums, int i, LinkedList<Integer> pre, List<List<Integer>> result) {
        result.add(new ArrayList<>(pre));
        for (int s = i; s < nums.length; s++) {
            // 一直到下一个不等于s位置元素的地方
            if (s > i && nums[s] == nums[s - 1]) {
                continue;
            }
            pre.add(nums[s]);
            p(nums, s + 1, pre, result);
            pre.remove(pre.size() - 1);
        }
    }
}

更多

算法和数据结构笔记

标签:pre,arr,nums,int,打印,子集,result,数组
From: https://www.cnblogs.com/greyzeng/p/16748973.html

相关文章

  • java将一个有序数组按是否连续进行分组
    代码:importjava.util.Arrays;importjava.util.Comparator;importjava.util.List;/***@authorliyinlong*@since2022/8/229:45上午*/publicclassSemTest{......
  • 后缀数组小结
    后缀数组小结借用了一下别人的\(\rmblog\)。简介介绍一下基本数组。我们把原串\(\rmA\)的所有后缀按字典序从小到大排个序,则排名为\(\rmi\)的字符串是以第\(......
  • 代码随想录 哈希表理论基础,有效的字母异位词(LeetCode 242),两个数组的交集 (LeetCode
    哈希表理论基础哈希表是根据关键码的值而直接进行访问的数据结构。哈希碰撞拉链法拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会......
  • 前端中数组的方法之 --- Array.prototype.reduce()
    参数:reduce((previousValue,currentValue,currentIndex,array)=>{/*…*/},initialValue)回调函数:previousValue:上一次调用 callbackFn 时的返回值。在第......
  • 数组操作の旋转二维数组
    一、题目描述:​​旋转图像​​给定一个n × n的二维矩阵 matrix表示一个图像。请你将图像顺时针旋转90度。你必须在原地旋转图像,这意味着你需要直接修改输入的二......
  • 机试题 三数之和变形-三数和赛高数组01
    数组a对任意的i、j、k都能找到l,使得ai+aj+ak=al,那么这个数组就是被称为三数和赛高数组,特别的i、j、k需要满足(1<=i<j<k<=n,1<=l<=n)。输入:首先t(1......
  • 机试题 三数之和变形-三数和赛高数组02 存在
    数组a存在i、j、k能找到l,使得ai+aj+ak=al,那么这个数组就是被称为三数和赛高数组,特别的i、j、k需要满足(1<=i<j<k<=n,1<=l<=n)。输入:首先t(1<=......
  • 稀疏数组
    稀疏数组packagearray;importjava.util.Arrays;publicclassSparse{publicstaticvoidmain(String[]args){//创建二维数组System.out.p......
  • Java 数组
    1.数组的定义数组是相同类型数据的有序集合。数字描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作数组元素,每一个数组元素可以通过......
  • 树状数组+dfs
    P3605[USACO17JAN]PromotionCountingP-洛谷|计算机科学教育新生态(luogu.com.cn)这是一棵树,首先想到了dfs,但是数据范围大,所以不能单纯用dfs想到每个结点只跟他的......