LeetCode 2166. 设计位集

该博客讨论了如何实现一个位集Bitset类,包括初始化、设置、清除、翻转、检查和转换等基本操作。通过使用vector<bool>和额外的计数变量,可以有效地管理位集并优化翻转操作。位集类支持判断所有位是否全为1、是否存在至少一位为1,以及计算1的个数,并能以字符串形式输出位集状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

位集 Bitset 是一种能以紧凑形式存储位的数据结构。

请你实现 Bitset 类。

Bitset(int size) 用 size 个位初始化 Bitset ,所有位都是 0 。
void fix(int idx) 将下标为 idx 的位上的值更新为 1 。如果值已经是 1 ,则不会发生任何改变。
void unfix(int idx) 将下标为 idx 的位上的值更新为 0 。如果值已经是 0 ,则不会发生任何改变。
void flip() 翻转 Bitset 中每一位上的值。换句话说,所有值为 0 的位将会变成 1 ,反之亦然。
boolean all() 检查 Bitset 中 每一位 的值是否都是 1 。如果满足此条件,返回 true ;否则,返回 false 。
boolean one() 检查 Bitset 中 是否 至少一位 的值是 1 。如果满足此条件,返回 true ;否则,返回 false 。
int 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 <= 105
0 <= idx <= size - 1
至多调用 fix、unfix、flip、all、one、count 和 toString 方法 总共 105 次
至少调用 all、one、count 或 toString 方法一次
至多调用 toString 方法 5 次

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-bitset
 

解法:

用vector<int> bs模拟bitset,用cnt来记录bs中1的个数,那么现在唯一卡时间的就是flip操作,flip操作为反转bs中的数字(0变1, 1变0),两次flip操作就变回了原来的数,那么用一个标记flag来表示是否处于奇数次flip中,用^1(异或)来执行反转操作(任何数与0异或都为原来的数,即使是0^0=0),0^1=1, 1^1=0,那么每次使用fix与unfix都要先与flag进行异或。

class Bitset {

    vector<bool> bs;
    int cnt;
    int flag;
public:
    Bitset(int size):bs(size), cnt(0), flag(0) {
    }
    
    void fix(int idx) {
       if((bs[idx] ^ flag) == 0)
       {
           bs[idx] = bs[idx] ^ 1;
           ++cnt;
       }
    }
    
    void unfix(int idx) {
        if((bs[idx] ^ flag) == 1)
        {
            bs[idx] = bs[idx] ^ 1;
           --cnt;
        }
    }
    
    void flip() {
        cnt = bs.size() - cnt;
        flag = flag ^ 1;
    }
    bool all() {
        if(cnt == bs.size())
            return true;
        return false;
    }
    
    bool one() {
        if(cnt > 0)
            return true;
        return false;
    }
    
    int count() {
        return cnt;
    }
    
    string toString() {
        string ans ;
        for(int i = 0; i< bs.size(); ++i)
        {
            ans.push_back('0' + (bs[i] ^ flag));
        }
        return ans;
    }
};

/**
 * Your Bitset object will be instantiated and called as such:
 * Bitset* obj = new Bitset(size);
 * obj->fix(idx);
 * obj->unfix(idx);
 * obj->flip();
 * bool param_4 = obj->all();
 * bool param_5 = obj->one();
 * int param_6 = obj->count();
 * string param_7 = obj->toString();
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值