2166. 设计位集

Problem: 2166. 设计位集

文章目录

  • 思路
  • 解题方法
  • 复杂度
  • 代码

思路

这道题要求设计一个位集(Bitset)类,实现以下功能:

  • 添加数字
  • 删除数字
  • 反转位集
  • 判断位集是否全为1
  • 判断位集是否至少有一个1
  • 统计位集中1的个数
  • 将位集转换为字符串表示

我们可以使用一个整型数组来存储位集的数据,每个整型数可以表示32个位。然后,我们可以使用位运算来实现各种功能。

解题方法

根据题目要求,我们可以设计一个 Bitset 类,其中包含以下成员变量:

  • set:整型数组,用于存储位集的数据
  • ones:整型变量,表示位集中1的个数
  • zeros:整型变量,表示位集中0的个数
  • reverse:布尔变量,表示位集是否反转
  • size:整型变量,表示位集的大小

然后,我们可以实现以下方法:

  • fix(int idx):添加数字到位集中。首先,我们需要计算数字在整型数组中的索引和位偏移量。然后,根据是否反转位集,判断是否需要添加数字到位集中,并更新相应的计数器。
  • unfix(int idx):从位集中删除数字。首先,我们需要计算数字在整型数组中的索引和位偏移量。然后,根据是否反转位集,判断是否需要从位集中删除数字,并更新相应的计数器。
  • flip():反转位集。将 reverse 变量取反,并交换 oneszeros 的值。
  • all():判断位集是否全为1。如果 ones 等于位集的大小,则返回 true,否则返回 false
  • one():判断位集是否至少有一个1。如果 ones 大于0,则返回 true,否则返回 false
  • count():统计位集中1的个数。直接返回 ones 的值。
  • toString():将位集转换为字符串表示。我们可以遍历整型数组中的每个整型数,然后将每个位的状态转换为字符,并拼接到字符串中。

复杂度

时间复杂度:添加数字和删除数字的时间复杂度为 O ( 1 ) O(1) O(1),反转位集、判断位集是否全为1、判断位集是否至少有一个1、统计位集中1的个数和将位集转换为字符串表示的时间复杂度为 O ( n ) O(n) O(n),其中 n 为位集的大小。

空间复杂度:整型数组的空间复杂度为 O ( n ) O(n) O(n),其中 n 为位集的大小。

代码

class Bitset {
    public int[] set;
    public int ones;
    public int zeros;
    public boolean reverse;

    public final int size;

    public Bitset(int n) {
        set = new int[(n + 31) / 32];
        size = n;
        ones = 0;
        zeros = n;
        reverse = false;
    }

    // 添加数字
    public void fix(int idx) {
        int index = idx / 32;
        int bit = idx % 32;
        if (!reverse) {
            if ((set[index] & (1 << bit)) == 0) {
                zeros--;
                ones++;
                set[index] |= (1 << bit);
            }
        } else {
            if ((set[index] & (1 << bit)) != 0) {
                zeros--;
                ones++;
                set[index] ^= (1 << bit);
            }
        }

    }

    // 删除数字
    public void unfix(int idx) {
        int index = idx / 32;
        int bit = idx % 32;
        if (!reverse) {
            if ((set[index] & (1 << bit)) != 0) {
                ones--;
                zeros++;
                set[index] ^= (1 << bit);
            }
        } else {
            if ((set[index] & (1 << bit)) == 0) {
                ones--;
                zeros++;
                set[index] |= (1 << bit);
            }
        }
    }

    public void flip() {
        reverse = !reverse;
        int tmp = zeros;
        zeros = ones;
        ones = tmp;
    }

    public boolean all() {
        return ones == size;
    }

    public boolean one() {
        return ones > 0;
    }

    public int count() {
        return ones;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0, k = 0, number, status; i < size; k++) {
            number = set[k];
            for (int j = 0; j < 32 && i < size; j++, i++) {
                status = (number >> j) & 1;
                status ^= reverse ? 1 : 0;
                sb.append(status);
            }
        }
        return sb.toString();
    }
}

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

你可能感兴趣的:(数据结构,算法,java,数据结构)