diff --git a/Cargo.lock b/Cargo.lock index e6ffc535..1172b52e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,10 @@ version = "0.1.0" name = "lc-0066-plus-one" version = "0.1.0" +[[package]] +name = "lc-0078-subsets" +version = "0.1.0" + [[package]] name = "lc-0083-remove-duplicates-from-sorted-list" version = "0.1.0" diff --git a/leetcode/0078.subsets/Cargo.toml b/leetcode/0078.subsets/Cargo.toml new file mode 100644 index 00000000..58a5f4d3 --- /dev/null +++ b/leetcode/0078.subsets/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "lc-0078-subsets" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] diff --git a/leetcode/0078.subsets/src/main.rs b/leetcode/0078.subsets/src/main.rs new file mode 100644 index 00000000..cfe18147 --- /dev/null +++ b/leetcode/0078.subsets/src/main.rs @@ -0,0 +1,65 @@ +// Copyright (c) 2023 Xu Shaohua . All rights reserved. +// Use of this source is governed by General Public License that can be +// found in the LICENSE file. + +pub fn get_all(out: &mut Vec>, data: &[T], chunk_len: usize) { + if chunk_len == 0 { + out.push(Vec::new()); + return; + } + if chunk_len == data.len() { + out.push(data.to_vec()); + return; + } + + let len = data.len(); + let min = 2_usize.pow(chunk_len as u32) - 1; + let mut mask = 2_usize.pow(len as u32) - 2_usize.pow((len - chunk_len) as u32); + + fn get_chunk(mask: usize, data: &[T]) -> Vec { + let b = format!("{:01$b}", mask, data.len()); + b.chars() + .enumerate() + .filter(|&(_, e)| e == '1') + .map(|(i, _)| data[i]) + .collect() + } + + while mask >= min { + if mask.count_ones() as usize == chunk_len { + let res = get_chunk(mask, data); + mask -= 1; + out.push(res); + } else { + mask -= 1; + } + } +} + +// Combinations +pub fn subsets(nums: Vec) -> Vec> { + let mut out = vec![]; + for i in 0..=nums.len() { + get_all(&mut out, &nums, i); + } + out +} + +fn main() { + let nums = vec![1, 2, 3]; + let expected_out = vec![ + vec![], + vec![1], + vec![2], + vec![3], + vec![1, 2], + vec![1, 3], + vec![2, 3], + vec![1, 2, 3], + ]; + assert_eq!(subsets(nums), expected_out); + + let nums = vec![0]; + let expected_out = vec![vec![], vec![0]]; + assert_eq!(subsets(nums), expected_out); +}