From db2fca022ecde6d1af4f8f0a30dc2607ee7c27b5 Mon Sep 17 00:00:00 2001 From: kr <963689810@qq.com> Date: Mon, 1 Jul 2024 15:12:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A00078.=E5=AD=90=E9=9B=86=20Rus?= =?UTF-8?q?t=E7=AC=AC=E4=BA=8C=E7=A7=8D=E6=80=9D=E8=B7=AF=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0078.子集.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0078.子集.md b/problems/0078.子集.md index 1415f2d2..723d99a1 100644 --- a/problems/0078.子集.md +++ b/problems/0078.子集.md @@ -287,6 +287,7 @@ function subsets(nums: number[]): number[][] { ### Rust +思路一:使用本题的标准解法,递归回溯。 ```Rust impl Solution { fn backtracking(result: &mut Vec>, path: &mut Vec, nums: &Vec, start_index: usize) { @@ -308,6 +309,30 @@ impl Solution { } } ``` +思路二:使用二进制枚举,n个元素的子集问题一共是$2^n$种情况。如果我们使用一个二进制数字,每一位根据0和1来决定是选取该元素与否,那么一共也是$2^n$的情况,正好可以一一对应,所以我们可以不使用递归,直接利用循环枚举完成子集问题。 +这种方法的优点在于效率高,不需要递归调用,并且代码容易编写。缺点则是过滤某些非法情况时会比递归方法难写一点,不过在子集问题中不存在这个问题。 +```Rust +impl Solution { + pub fn subsets(nums: Vec) -> Vec> { + let n = nums.len(); + // 预分配2^n空间 + let mut result = Vec::with_capacity(1 << n); + // 二进制枚举,2^n种情况 + for i in 0..(1 << n) { + let mut subset = Vec::new(); + for j in 0..n { + // 枚举该二进制数字的每一位 + // 如果该位是1,对应位置上的元素加入子集,否则跳过 + if i & (1 << j) != 0 { + subset.push(nums[j]); + } + } + result.push(subset); + } + result + } +} +``` ### C