打印数组的所有子集

时间:2020-07-15 04:58:16

标签: java

我正在尝试打印数组的所有子集。例如:

Lnput

我已经写了一种递归方法,因为所有这些解决方案都以一个条件开头,并且程序调用了自己的子数组。但是我在Warning: validateDOMNesting(...): <div> cannot appear as a child of <select>.得到了Input: nums = [1,2] Output: [[1], [2], [1,2], []]

如何解决问题并将其转换为可行的解决方案?

更新:我不需要有效的解决方案。我需要修复自己的代码。请在下面使用我自己的代码:

ConcurrentModificationException

3 个答案:

答案 0 :(得分:3)

在迭代列表时不要将元素添加到列表中。通过选择每次采用或不采用当前元素,可以大大简化您的代码。 Demo

src/

您还可以使用位掩码。 Demo

public static Set<List<Integer>> subsets(Set<List<Integer>> result, ArrayList<Integer> curr, int[] nums, int idx) {
    result.add((List<Integer>)curr.clone());
    if(idx < nums.length){
         subsets(result, curr, nums, idx + 1);
         final ArrayList<Integer> next = (ArrayList<Integer>) curr.clone();
         next.add(nums[idx]);
         subsets(result, next, nums, idx + 1);
    }
    return result;
}
public static void main(String[] args){
    int[] x = {1,2};
    System.out.println(subsets(new HashSet<>(), new ArrayList<>(), x, 0));
}

答案 1 :(得分:1)

可以使用IterativeRecursive两种方法来解决

  • 对于此问题,与LinkedList相比,使用ArrayList的速度更快
  • 此外,nums.length == 1
  • 也不需要处理

迭代方法

import java.util.LinkedList;
import java.util.List;

public class TestPractice {
    public static void main(String[] args) {
        int[] x = { 1, 2 };
        System.out.println(subsets(x));
    }

    public static List<LinkedList<Integer>> subsets(int[] nums) {
        LinkedList<LinkedList<Integer>> subsets = new LinkedList<LinkedList<Integer>>();
        subsets.add(new LinkedList<Integer>());
        for(int i = 0; i < nums.length; i++) {

            LinkedList<LinkedList<Integer>> temp = new LinkedList<LinkedList<Integer>>();
            for(LinkedList<Integer> l1: subsets) {
                LinkedList<Integer> l2 = new LinkedList<Integer>(l1);
                l2.add(nums[i]);
                temp.add(l2);
            }
            subsets.addAll(temp);
        }

        return subsets;
    }
}

递归方法

import java.util.LinkedList;
import java.util.List;

public class TestPractice {
    public static void main(String[] args) {
        int[] x = { 1, 2 };
        System.out.println(subsets(x));
    }

    public static List<List<Integer>> subsets(int n[]) {
        List<List<Integer>> subsets = new LinkedList<List<Integer>>();
        helper(n, 0, subsets, new LinkedList<Integer>());
        return subsets;
    }

    public static void helper(int[] n, int i, List<List<Integer>> subsets, LinkedList<Integer> subset1) {
        if(i == n.length) {
            subsets.add(subset1);
            return;
        }
        helper(n, i + 1, subsets, subset1);
        LinkedList<Integer> subset2 = new LinkedList<Integer>(subset1);
        subset2.add(n[i]);
        helper(n, i + 1, subsets, subset2);
    }
}

答案 2 :(得分:1)

concurrentmodificationexception在循环和更新同一列表时发生,因此请创建一个新列表并在循环内而不是subsets2.add(subset1)中更新该列表。

下面,我创建了一个新列表result并在循环内而不是result内更新了subset2列表

import java.util.ArrayList;
import java.util.List;
public class TestPractice {
    public static void main(String[] args){
        int[] x = {1,2};
        System.out.println(subsets(x));
    }
    
    public static List<ArrayList<Integer>> subsets(int[] nums) {
        ArrayList<ArrayList<Integer>> subsets = new ArrayList<ArrayList<Integer>>();
        if (nums.length ==1){
            ArrayList<Integer> subset1 = new ArrayList<Integer>();
            ArrayList<Integer> subset2 = new ArrayList<Integer>();
            subset2.add(nums[0]);
            subsets.add(subset1);
            subsets.add(subset2);
            return subsets;
        }
        int[] nums_1 = new int[nums.length-1];
        for(int i = 0; i< nums.length-1; i++) {
        nums_1[i]=nums[i];
        }
        
        List<ArrayList<Integer>> subsets2= subsets(nums_1); 
        List<ArrayList<Integer>> result= subsets(nums_1); 
        //now add nums[n] to all subsets of nums[0:n-1]
        for(ArrayList<Integer>subset: subsets2) {
            ArrayList<Integer> subset1 = new ArrayList<Integer>();
            subset1.add(nums[nums.length-1]);
            subset1.addAll(subset);
            result.add(subset1);
        }
        return result;
    }
    
    
}