Leetcode 78.子集

题目描述

Leetcode 78.子集_第1张图片

解题思路

方法三:字典排序(二进制排序) 子集 思路

该方法思路来自于 Donald E. Knuth。

将每个子集映射到长度为 n 的位掩码中,其中第 i 位掩码 nums[i] 为 1,表示第 i 个元素在子集中;如果第 i 位掩码
nums[i] 为 0,表示第 i 个元素不在子集中。

Leetcode 78.子集_第2张图片

例如,位掩码 0…00(全 0)表示空子集,位掩码 1…11(全 1)表示输入数组 nums。

因此要生成所有子集,只需要生成从 0…00 到 1…11 的所有 n 位掩码。

乍看起来生成二进制数很简单,但如何处理左边填充 0 是一个问题。因为必须生成固定长度的位掩码:例如 001,而不是
1。因此可以使用一些位操作技巧

代码实现

public class Solution 
{
    public IList<IList<int>> Subsets(int[] nums)
 {
            
            int num = 1;

            for(int i=1;i<=nums.Length;i++)
	        {
                num*=2;  
            }
            num-=1;  //获取非空子集长度
            IList<IList<int>> result = new List<IList<int>> ();
            for(int j=0; j<=num; j++)  //j是每个子集的位数 以数组长度为3 num为4 为例 用二进制表示就是j为00 01 10 11
           {
                IList<int> once = new List<int>();  //初始化每一个子集
                for(int k=0; k<nums.Length; k++)  //nums.Length 数组长度
	              {
                    int bit = 1<<k;               
                    if((j&bit)!=0)                //一位一位看j的某位是不是1 是1的话结果就是非0 是0的话结果就是0 
		               {
                        once.Add(nums[k]);       //子集里应该有1位置的数就加进去
                        }
                  }
                result.Add(once); //把子集加进去
           }
   
            return result;
 }
}

你可能感兴趣的:(力扣题目,难以参透)