设计位集
- https://leetcode.cn/problems/design-bitset/description/
描述
- 位集 Bitset 是一种能以紧凑形式存储位的数据结构。请你实现 Bitset 类。
Bitset(int size)
用 size 个位初始化 Bitset ,所有位都是 0void fix(int idx)
将下标为 idx 的位上的值更新为 1 。如果值已经是 1 ,则不会发生任何改变void unfix(int idx)
将下标为 idx 的位上的值更新为 0 。如果值已经是 0 ,则不会发生任何改变void flip()
翻转 Bitset 中每一位上的值。换句话说,所有值为 0 的位将会变成 1 ,反之亦然boolean all()
检查 Bitset 中 每一位 的值是否都是 1 。如果满足此条件,返回 true ;否则,返回 falseboolean one()
检查 Bitset 中 是否 至少一位 的值是 1 。如果满足此条件,返回 true ;否则,返回 falseint count()
返回 Bitset 中值为 1 的位的 总数String toString()
返回 Bitset 的当前组成情况。注意,在结果字符串中,第 i 个下标处的字符应该与 Bitset 中的第 i 位一致
示例
输入
["Bitset", "fix", "fix", "flip", "all", "unfix", "flip", "one", "unfix", "count", "toString"]
[[5], [3], [1], [], [], [0], [], [], [0], [], []]
输出
[null, null, null, null, false, null, null, true, null, 2, "01010"]
解释
Bitset bs = new Bitset(5); // bitset = "00000".
bs.fix(3); // 将 idx = 3 处的值更新为 1 ,此时 bitset = "00010" 。
bs.fix(1); // 将 idx = 1 处的值更新为 1 ,此时 bitset = "01010" 。
bs.flip(); // 翻转每一位上的值,此时 bitset = "10101" 。
bs.all(); // 返回 False ,bitset 中的值不全为 1 。
bs.unfix(0); // 将 idx = 0 处的值更新为 0 ,此时 bitset = "00101" 。
bs.flip(); // 翻转每一位上的值,此时 bitset = "11010" 。
bs.one(); // 返回 True ,至少存在一位的值为 1 。
bs.unfix(0); // 将 idx = 0 处的值更新为 0 ,此时 bitset = "01010" 。
bs.count(); // 返回 2 ,当前有 2 位的值为 1 。
bs.toString(); // 返回 "01010" ,即 bitset 的当前组成情况。
提示
- 1 <= size <= 1 0 5 10^5 105
- 0 <= idx <= size - 1
- 至多调用 fix、unfix、flip、all、one、count 和 toString 方法 总共 1 0 5 10^5 105 次
- 至少调用 all、one、count 或 toString 方法一次
- 至多调用 toString 方法 5 次
Typescript 版算法实现
1 ) 方案1:利用数组实现
class Bitset {private arr: number[]; // 存储每一位的数组private cnt: number; // 1 的个数private reversed: number; // 反转操作的次数奇偶性(0 或 1)constructor(size: number) {this.arr = new Array(size).fill(0);this.cnt = 0;this.reversed = 0;}fix(idx: number): void {if ((this.arr[idx] ^ this.reversed) === 0) {this.arr[idx] ^= 1;this.cnt++;}}unfix(idx: number): void {if ((this.arr[idx] ^ this.reversed) === 1) {this.arr[idx] ^= 1;this.cnt--;}}flip(): void {this.reversed ^= 1;this.cnt = this.arr.length - this.cnt;}all(): boolean {return this.cnt === this.arr.length;}one(): boolean {return this.cnt > 0;}count(): number {return this.cnt;}toString(): string {let res = '';for (let bit of this.arr) {res += (bit ^ this.reversed).toString();}return res;}
}/*** Your Bitset object will be instantiated and called as such:* var obj = new Bitset(size)* obj.fix(idx)* obj.unfix(idx)* obj.flip()* var param_4 = obj.all()* var param_5 = obj.one()* var param_6 = obj.count()* var param_7 = obj.toString()*/
2 ) 方案2:另一种方式
class Bitset {private set: number[]; // 存储位的数组,每个元素存储32位private n: number; // 总位数private ones: number; // 当前1的数量private reverse: number; // 反转操作的次数奇偶性constructor(size: number) {this.n = size;this.set = new Array(Math.ceil(size / 32)).fill(0);this.ones = 0;this.reverse = 0;}fix(idx: number): void {const index = Math.floor(idx / 32);const bit = idx % 32;const flag = (this.set[index] >> bit) & 1;if ((this.reverse ^ flag) === 0) {this.set[index] ^= 1 << bit;++this.ones;}}unfix(idx: number): void {const index = Math.floor(idx / 32);const bit = idx % 32;const flag = (this.set[index] >> bit) & 1;if ((this.reverse ^ flag) === 1) {this.set[index] ^= 1 << bit;--this.ones;}}flip(): void {this.reverse ^= 1;this.ones = this.n - this.ones;}all(): boolean {return this.ones === this.n;}one(): boolean {return this.ones > 0;}count(): number {return this.ones;}toString(): string {let res: string = '';for (let i = 0; i < this.n; i++) {const index = Math.floor(i / 32);const bit = i % 32;const flag = (this.set[index] >> bit) & 1;res += this.reverse ^ flag;}return res;}
}/*** Your Bitset object will be instantiated and called as such:* var obj = new Bitset(size)* obj.fix(idx)* obj.unfix(idx)* obj.flip()* var param_4 = obj.all()* var param_5 = obj.one()* var param_6 = obj.count()* var param_7 = obj.toString()*/