力扣0090——子集II

子集

难度:中等

题目描述

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

示例1

输入: nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]

示例2

输入: nums = [0]
输出:[[],[0]]

题解

先将数组排序,生成所有的子集,排序之后相同的元素位于相邻的位置,利用这一特点去重
去重操作主要是判断前一个数和当前数字是否相等,如果不相等就继续进行之后的操作,相等则跳出本次回溯
当遍历到数组中下标为i的数时,执行如下操作:

  • 如果 i = n i = n i=n,那么得到一个子集,将子集添加到答案中
  • 如果 i < n i < n i<n,则分别考虑将其加入到子集和不加入到子集中两种情况
    • 不将其加入子集则继续对 i + 1 i + 1 i+1 进行回溯
    • 如果可以加入到子集中,则将其加入到子集中之后继续回溯,回溯之后将当前子集的末尾元素移除,恢复到初始状态

遍历结束之后,就可以得到最终答案

想法代码

public class Solution
{
    public static void Main(String[] args)
    {
        int[] nums = { 1, 2, 2 };
        Solution solution = new Solution();
        IList<IList<int>> ans = new List<IList<int>>();
        ans = solution.SubsetsWithDup(nums);
        foreach (var i in ans)
        {
            foreach (var j in i)
            {
                Console.Write(j + " ");
            }

            Console.WriteLine();
        }
    }

    IList<IList<int>> powerSet = new List<IList<int>>();
    IList<int> temp = new List<int>();
    int[] nums;
    int n;

    public IList<IList<int>> SubsetsWithDup(int[] nums)
    {
        Array.Sort(nums);
        this.nums = nums;
        this.n = nums.Length;
        Backtrack(0, false);
        return powerSet;
    }

    public void Backtrack(int index, bool prevSelected)
    {
        if (index == n)
        {
            powerSet.Add(new List<int>(temp));
        }
        else
        {
            Backtrack(index + 1, false);
            if (index == 0 || nums[index - 1] != nums[index] || prevSelected)
            {
                temp.Add(nums[index]);
                Backtrack(index + 1, true);
                temp.RemoveAt(temp.Count - 1);
            }
        }
    }
}

你可能感兴趣的:(算法进修,leetcode,算法,职场和发展)