📑 题目:78. 子集

🚀 本题 LeetCode 传送门

题目大意

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。

解题思路

  • 找出一个集合中的所有子集,空集也算是子集。且数组中的数字不会出现重复。用 DFS 暴力枚举即可。
  • 这一题和第 90 题,第 491 题类似,可以一起解答和复习。

代码

  1. package leetcode
  2. import ""sort""
  3. // 解法一
  4. func subsets(nums []int) [][]int {
  5. c, res := []int{}, [][]int{}
  6. for k := 0; k <= len(nums); k++ {
  7. generateSubsets(nums, k, 0, c, &res)
  8. }
  9. return res
  10. }
  11. func generateSubsets(nums []int, k, start int, c []int, res *[][]int) {
  12. if len(c) == k {
  13. b := make([]int, len(c))
  14. copy(b, c)
  15. *res = append(*res, b)
  16. return
  17. }
  18. // i will at most be n - (k - c.size()) + 1
  19. for i := start; i < len(nums)-(k-len(c))+1; i++ {
  20. c = append(c, nums[i])
  21. generateSubsets(nums, k, i+1, c, res)
  22. c = c[:len(c)-1]
  23. }
  24. return
  25. }
  26. // 解法二
  27. func subsets1(nums []int) [][]int {
  28. res := make([][]int, 1)
  29. sort.Ints(nums)
  30. for i := range nums {
  31. for _, org := range res {
  32. clone := make([]int, len(org), len(org)+1)
  33. copy(clone, org)
  34. clone = append(clone, nums[i])
  35. res = append(res, clone)
  36. }
  37. }
  38. return res
  39. }
  40. // 解法三:位运算的方法
  41. func subsets2(nums []int) [][]int {
  42. if len(nums) == 0 {
  43. return nil
  44. }
  45. res := [][]int{}
  46. sum := 1 << uint(len(nums))
  47. for i := 0; i < sum; i++ {
  48. stack := []int{}
  49. tmp := i // i 从 000...000 到 111...111
  50. for j := len(nums) - 1; j >= 0; j-- { // 遍历 i 的每一位
  51. if tmp & 1 == 1 {
  52. stack = append([]int{nums[j]}, stack...)
  53. }
  54. tmp >>= 1
  55. }
  56. res = append(res, stack)
  57. }
  58. return res
  59. }