Skip to content

Commit

Permalink
leetcode: Add subsets
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Dec 8, 2023
1 parent c26db33 commit 3b7dc62
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions leetcode/0078.subsets/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "lc-0078-subsets"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
65 changes: 65 additions & 0 deletions leetcode/0078.subsets/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2023 Xu Shaohua <[email protected]>. 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<T: Copy>(out: &mut Vec<Vec<T>>, 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<T: Copy>(mask: usize, data: &[T]) -> Vec<T> {
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<i32>) -> Vec<Vec<i32>> {
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);
}

0 comments on commit 3b7dc62

Please sign in to comment.