携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
面试题 08.04. 幂集:
幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。
说明:解集不能包含重复的子集。
样例 1:
输入:
nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
分析
- 面对这道算法题目,二当家的陷入了沉思。
- 由于没有重复数字,所以就是取不重复的任意组合。
- 假设集合中有n个元素,每个数字都可以选择或者不选择,那么子集的数量就是个。
题解
java
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
// 空集合(所有数字都不选)
ans.add(new ArrayList<>());
for (int num : nums) {
// 之前的结果是没有选择当前数字的集合,遍历之前的结果与当前数字组成新的集合,表示选择当前数字的集合
for (int i = 0, j = ans.size(); i < j; i++) {
List<Integer> list = new ArrayList<>(ans.get(i));
// 选择当前数字
list.add(num);
// 放入结果
ans.add(list);
}
}
return ans;
}
}
c
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
*returnSize = 0;
*returnColumnSizes = (int*) malloc((1 << numsSize) * sizeof (int));
int** ans = (int**) malloc((1 << numsSize) * sizeof (int*));
// 空集合(所有数字都不选)
(*returnColumnSizes)[(*returnSize)++] = 0;
ans[0] = NULL;
for (int i = 0; i < numsSize; i++) {
// 之前的结果是没有选择当前数字的集合,遍历之前的结果与当前数字组成新的集合,表示选择当前数字的集合
for (int j = 0, size = *returnSize; j < size; j++) {
int size = (*returnColumnSizes)[j];
// 多申请一个保存当前循环数字
int* tmp = (int*) malloc((size + 1) * sizeof(int));
if (size > 0) {
// 复制原子集
memcpy(tmp, ans[j], size * sizeof(int));
}
// 选择当前数字组成新子集
tmp[size++] = nums[i];
// 放入结果
(*returnColumnSizes)[*returnSize] = size;
ans[(*returnSize)++] = tmp;
}
}
return ans;
}
c++
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> ans;
// 空集合(所有数字都不选)
ans.push_back({});
for (int num : nums) {
// 之前的结果是没有选择当前数字的集合,遍历之前的结果与当前数字组成新的集合,表示选择当前数字的集合
for (int i = 0, j = ans.size(); i < j; i++) {
vector<int> tmp = ans[i];
// 选择当前数字
tmp.emplace_back(num);
// 放入结果
ans.emplace_back(tmp);
}
}
return ans;
}
};
python
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
# 空集合(所有数字都不选)
ans = [[], ]
for num in nums:
# 之前的结果是没有选择当前数字的集合,遍历之前的结果与当前数字组成新的集合,表示选择当前数字的集合
ans += [row + [num] for row in ans]
return ans
go
func subsets(nums []int) [][]int {
ans := make([][]int, 0)
// 空集合(所有数字都不选)
ans = append(ans, []int{})
for _, num := range nums {
// 之前的结果是没有选择当前数字的集合,遍历之前的结果与当前数字组成新的集合,表示选择当前数字的集合
for i, j := 0, len(ans); i < j; i++ {
tmp := make([]int, 0)
tmp = append(tmp, ans[i]...)
// 选择当前数字
tmp = append(tmp, num)
// 放入结果
ans = append(ans, tmp)
}
}
return ans
}
rust
impl Solution {
pub fn subsets(nums: Vec<i32>) -> Vec<Vec<i32>> {
let mut ans = Vec::new();
// 空集合(所有数字都不选)
ans.push(Vec::new());
nums.iter().for_each(|num|{
// 之前的结果是没有选择当前数字的集合,遍历之前的结果与当前数字组成新的集合,表示选择当前数字的集合
(0..ans.len()).for_each(|i|{
let mut tmp = ans[i].clone();
// 选择当前数字
tmp.push(*num);
// 放入结果
ans.push(tmp);
});
});
ans
}
}
typescript
function subsets(nums: number[]): number[][] {
// 空集合(所有数字都不选)
const ans: number[][] = [[]];
for (let i in nums) {
// 之前的结果是没有选择当前数字的集合,遍历之前的结果与当前数字组成新的集合,表示选择当前数字的集合
for (let j in ans) {
const tmp: number[] = [...ans[j]];
// 选择当前数字
tmp.push(nums[i]);
// 放入结果
ans.push(tmp);
}
}
return ans;
};
原题传送门:https://leetcode-cn.com/problems/power-set-lcci/
非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://juejin.cn/user/2771185768884824/posts 博客原创~