LeetCode 78. 子集

leetcode.cn/problems/su...

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

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

示例 1:

ini 复制代码
输入: nums = [1,2,3]
输出: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

lua 复制代码
输入: nums = [0]
输出: [[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

方法1:递归

代码

遍历写法:

kotlin 复制代码
class Solution {
    fun subsets(nums: IntArray): List<List<Int>> {
        val resultList = mutableListOf<List<Int>>()
        // 在输出结果中加入空集
        resultList.add(listOf())
        for (i in nums) {
            val newSubsetList = mutableListOf<List<Int>>()
            for (ints in resultList) {
                // 复制结果中已经存在的子集
                val newSubset = mutableListOf<Int>()
                newSubset.addAll(ints)
                // 加入当前整数
                newSubset.add(i)
                // 加入输出结果
                newSubsetList.add(newSubset)
            }
            resultList.addAll(newSubsetList)
        }
        return resultList
    }
}

递归写法:

kotlin 复制代码
class Solution {
    fun subsets(nums: IntArray): List<List<Int>> {
        return recurse(cur = nums.size, nums = nums)
    }

    // 返回 nums 中前 cur 个数的所有子集
    fun recurse(cur: Int, nums: IntArray): List<List<Int>> {
        val result = mutableListOf<List<Int>>()
        // 前 0 个数的子集为 [[]]
        if (cur == 0) {
            result.add(listOf())
            return result
        }
        // 前 cur-1 个数中所有子集
        val existingResult = recurse(cur - 1, nums)
        result.addAll(existingResult)
        for (ints in existingResult) {
            val newSubset = mutableListOf<Int>()
            newSubset.addAll(ints)
            // 加入一个新的数
            newSubset.add(nums[cur - 1])
            result.add(newSubset)
        }
        return result
    }
}

方法2:回溯

kotlin 复制代码
class Solution {
    val result = mutableListOf<List<Int>>()
    var n: Int = 0

    fun subsets(nums: IntArray): List<List<Int>> {
        n = nums.size
        for (k in 0..n) {
            backtrack(0, k, mutableListOf(), nums)
        }
        return result
    }

    /**
     * start 为子集第一个数在 nums 中最早可以出现的位置
     * k 为当前需要构造子集的长度
     * cur 储存当前正在构造的子集
     * backtrack 运行一次能够构造所有长度为 k 的子集
     */
    fun backtrack(start: Int, k: Int, cur: MutableList<Int>, nums: IntArray) {
        // 当前子集构造完成
        // 将 cur 中的子集加入输出结果
        if (k == 0) {
            val subset = mutableListOf<Int>()
            subset.addAll(cur)
            result.add(subset)
            return
        }
        for (i in start..<n) {
            // 把数组中第 i 个数加入当前子集
            cur.add(nums[i])
            // 从 i+1 位置开始继续构建当前子集
            backtrack(i + 1, k - 1, cur, nums)
            // 把这步加入的数字从数组中移除
            cur.removeAt(cur.size - 1)
        }
    }
}

方法3:字典排序子集

kotlin 复制代码
class Solution {
    fun subsets(nums: IntArray): List<List<Int>> {
        val result = mutableListOf<List<Int>>()
        val n = nums.size

        for (i in 2f.pow(n).toInt()..<2f.pow(n + 1).toInt()) {
//            生成 01 字符串
//            bitmask = 000
//            bitmask = 001
//            bitmask = 010
//            bitmask = 011
//            bitmask = 100
//            bitmask = 101
//            bitmask = 110
//            bitmask = 111
            val bitmask = Integer.toBinaryString(i).substring(1)
            val subset = mutableListOf<Int>()
            for (j in 0..<n) {
                // 对于 nums 中的每个数,如果字符串中该数位为1则加入子集,反之则跳过
                if (bitmask[j] == '1') {
                    subset.add(nums[i])
                }
            }
            result.add(subset)
        }
        return result
    }
}
相关推荐
CQU_JIAKE8 分钟前
9.30【A】
算法
INGNIGHT23 分钟前
1897 · 会议室 3(扫描线)
数据结构·算法
All for pursuit.25 分钟前
【贪心-2】253.会议室 II
数据结构·c++·算法·leetcode
垆边人似月.26 分钟前
华为机考题(一):质数因子
算法·华为
迷途之人不知返1 小时前
算法系列5:位运算
算法
牢姐与蒯1 小时前
c++加餐之位图
c++·算法·哈希
Omics Pro1 小时前
预测性虚拟细胞中显式机理算子
大数据·数据库·人工智能·python·算法·机器学习·自然语言处理
驭渊的小故事1 小时前
算法实战:滑动窗口、素数枚举与字符串模拟(三道经典题解)
java·算法
牢姐与蒯1 小时前
位运算及其oj题
c++·算法
小蒋学算法11 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法