Skip to content

Commit aaf08fe

Browse files
committed
1 parent e0e3d6b commit aaf08fe

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

src/solution/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,3 +1637,4 @@ mod s2162_minimum_cost_to_set_cooking_time;
16371637
mod s2163_minimum_difference_in_sums_after_removal_of_elements;
16381638
mod s2164_sort_even_and_odd_indices_independently;
16391639
mod s2165_smallest_value_of_the_rearranged_number;
1640+
mod s2166_design_bitset;
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* [2166] Design Bitset
3+
*
4+
* A Bitset is a data structure that compactly stores bits.
5+
* Implement the Bitset class:
6+
*
7+
* Bitset(int size) Initializes the Bitset with size bits, all of which are 0.
8+
* void fix(int idx) Updates the value of the bit at the index idx to 1. If the value was already 1, no change occurs.
9+
* void unfix(int idx) Updates the value of the bit at the index idx to 0. If the value was already 0, no change occurs.
10+
* void flip() Flips the values of each bit in the Bitset. In other words, all bits with value 0 will now have value 1 and vice versa.
11+
* boolean all() Checks if the value of each bit in the Bitset is 1. Returns true if it satisfies the condition, false otherwise.
12+
* boolean one() Checks if there is at least one bit in the Bitset with value 1. Returns true if it satisfies the condition, false otherwise.
13+
* int count() Returns the total number of bits in the Bitset which have value 1.
14+
* String toString() Returns the current composition of the Bitset. Note that in the resultant string, the character at the i^th index should coincide with the value at the i^th bit of the Bitset.
15+
*
16+
*
17+
* Example 1:
18+
*
19+
* Input
20+
* ["Bitset", "fix", "fix", "flip", "all", "unfix", "flip", "one", "unfix", "count", "toString"]
21+
* [[5], [3], [1], [], [], [0], [], [], [0], [], []]
22+
* Output
23+
* [null, null, null, null, false, null, null, true, null, 2, "01010"]
24+
* Explanation
25+
* Bitset bs = new Bitset(5); // bitset = "00000".
26+
* bs.fix(3); // the value at idx = 3 is updated to 1, so bitset = "00010".
27+
* bs.fix(1); // the value at idx = 1 is updated to 1, so bitset = "01010".
28+
* bs.flip(); // the value of each bit is flipped, so bitset = "10101".
29+
* bs.all(); // return False, as not all values of the bitset are 1.
30+
* bs.unfix(0); // the value at idx = 0 is updated to 0, so bitset = "00101".
31+
* bs.flip(); // the value of each bit is flipped, so bitset = "11010".
32+
* bs.one(); // return True, as there is at least 1 index with value 1.
33+
* bs.unfix(0); // the value at idx = 0 is updated to 0, so bitset = "01010".
34+
* bs.count(); // return 2, as there are 2 bits with value 1.
35+
* bs.toString(); // return "01010", which is the composition of bitset.
36+
*
37+
*
38+
* Constraints:
39+
*
40+
* 1 <= size <= 10^5
41+
* 0 <= idx <= size - 1
42+
* At most 10^5 calls will be made in total to fix, unfix, flip, all, one, count, and toString.
43+
* At least one call will be made to all, one, count, or toString.
44+
* At most 5 calls will be made to toString.
45+
*
46+
*/
47+
pub struct Solution {}
48+
49+
// problem: https://leetcode.com/problems/design-bitset/
50+
// discuss: https://leetcode.com/problems/design-bitset/discuss/?currentPage=1&orderBy=most_votes&query=
51+
52+
// submission codes start here
53+
54+
// Credit: https://leetcode.com/problems/design-bitset/solutions/4344356/rust-bitset/
55+
56+
struct Bitset {
57+
bitsets: Vec<u32>,
58+
last_bitset_mask: u32,
59+
}
60+
61+
/**
62+
* `&self` means the method takes an immutable reference.
63+
* If you need a mutable reference, change it to `&mut self` instead.
64+
*/
65+
impl Bitset {
66+
fn new(size: i32) -> Self {
67+
Self {
68+
bitsets: vec![0; (size as usize + 31) / 32],
69+
last_bitset_mask: (1 << 32 - size % 32) - 1,
70+
}
71+
}
72+
73+
fn fix(&mut self, idx: i32) {
74+
self.bitsets[idx as usize / 32] |= 1 << 31 - idx % 32;
75+
}
76+
77+
fn unfix(&mut self, idx: i32) {
78+
self.bitsets[idx as usize / 32] &= !(1 << 31 - idx % 32);
79+
}
80+
81+
fn flip(&mut self) {
82+
for bitset in &mut self.bitsets {
83+
*bitset = !*bitset;
84+
}
85+
}
86+
87+
fn all(&self) -> bool {
88+
self.bitsets[..self.bitsets.len() - 1]
89+
.iter()
90+
.all(|&bitset| bitset == u32::MAX)
91+
&& self.bitsets[self.bitsets.len() - 1] | self.last_bitset_mask == u32::MAX
92+
}
93+
94+
fn one(&self) -> bool {
95+
self.bitsets[..self.bitsets.len() - 1]
96+
.iter()
97+
.any(|&bitset| bitset > 0)
98+
|| self.bitsets[self.bitsets.len() - 1] & !(self.last_bitset_mask) > 0
99+
}
100+
101+
fn count(&self) -> i32 {
102+
self.bitsets[..self.bitsets.len() - 1]
103+
.iter()
104+
.map(|bitset| bitset.count_ones() as i32)
105+
.sum::<i32>()
106+
+ (self.bitsets[self.bitsets.len() - 1] & !(self.last_bitset_mask)).count_ones() as i32
107+
}
108+
109+
fn to_string(&self) -> String {
110+
let mut out = String::with_capacity(self.bitsets.len() * 32);
111+
for &bitset in &self.bitsets[..self.bitsets.len() - 1] {
112+
std::fmt::Write::write_fmt(&mut out, format_args!("{:032b}", bitset));
113+
}
114+
std::fmt::Write::write_fmt(
115+
&mut out,
116+
format_args!("{:032b}", self.bitsets[self.bitsets.len() - 1]),
117+
);
118+
out.truncate(out.len() - self.last_bitset_mask.count_ones() as usize);
119+
out
120+
}
121+
}
122+
123+
/**
124+
* Your Bitset object will be instantiated and called as such:
125+
* let obj = Bitset::new(size);
126+
* obj.fix(idx);
127+
* obj.unfix(idx);
128+
* obj.flip();
129+
* let ret_4: bool = obj.all();
130+
* let ret_5: bool = obj.one();
131+
* let ret_6: i32 = obj.count();
132+
* let ret_7: String = obj.to_string();
133+
*/
134+
135+
// submission codes end
136+
137+
#[cfg(test)]
138+
mod tests {
139+
use super::*;
140+
141+
#[test]
142+
fn test_2166_example_1() {
143+
let mut bs = Bitset::new(5); // bitset = "00000".
144+
bs.fix(3); // the value at idx = 3 is updated to 1, so bitset = "00010".
145+
bs.fix(1); // the value at idx = 1 is updated to 1, so bitset = "01010".
146+
bs.flip(); // the value of each bit is flipped, so bitset = "10101".
147+
assert_eq!(bs.all(), false); // return False, as not all values of the bitset are 1.
148+
bs.unfix(0); // the value at idx = 0 is updated to 0, so bitset = "00101".
149+
bs.flip(); // the value of each bit is flipped, so bitset = "11010".
150+
assert_eq!(bs.one(), true); // return True, as there is at least 1 index with value 1.
151+
bs.unfix(0); // the value at idx = 0 is updated to 0, so bitset = "01010".
152+
assert_eq!(bs.count(), 2); // return 2, as there are 2 bits with value 1.
153+
assert_eq!(bs.to_string(), "01010".to_string()); // return "01010", which is the composition of bitset.
154+
}
155+
}

0 commit comments

Comments
 (0)