位图数组

介绍

要判断一千万个整数中是否存在某个数,如何查找?简单的想法是创建一个一千万大小的数组,然后遍历查找,这样即耗费空间又耗费时间。所以我们可以创建位图数组。

实际上这个数组就是个普通数组byte, int, long类型都可以,只不过我们每次操作的是数组中一个元素的其中一位。如果要加入一个数字11,那么我们就设置这个位图数组的第11位1,就代表这个数存在。

比如用byte类型实现一个位图数组。由于byte类型是八位,所以我们就可以数组大小为实际需求的容量/8。如果是int类型就除以32。

所以bytes[0] 就代表了位图的[0, 7]位, byte[1] 就代表了位图的[8, 15]位, 依次...

不过由于是从零开始,所以如果要对负数进行操作时,需要加上一个offset使所有数据变成非负,方便操作。

static class MyBitMap {
    
    

    private byte[] bitmap;
    private final int bit = 8;

    public MyBitMap(int size) {
    
    
      if (size <= 0) return;
      int initSize = size / bit + 1;
      bitmap = new byte[initSize];
    }

    public void set(int number) {
    
    
      //除以8,代表这个数字在数组中的下标
      //因为我们要找这个数字在整个位图中位于哪一位,而一个数组元素是8位
      //所以除以8就能找到(它对应的位所在的byte类型数据)在数组中的位置。
      int index = number / bit;
      //number % 8 获取到在这个byte类型中,它处于哪一位
      int position = number % bit;
      //进行或运算,即把number对应的位修改为1。
      bitmap[index] |= 1 << (bit - 1 - position);
    }


    public boolean contains(int number) {
    
    
      //在查找这个数和set方法一样,先获得对应数组中的位置
      int index = number / bit;
      //再获取这个元素中对应位的位置
      int position = number % bit;
      //查看对应位是不是1
      return (bitmap[index] & (1 << (bit - 1 - position))) != 0;
    }
  }

例题实现:【LC存在重复元素】链接

class Solution {
    
    
  static class MyBitMap {
    
    

    private int[] bitmap;
    private final int bit = 32;

    public MyBitMap(int size) {
    
    
      if (size <= 0) return;
      int initSize = size / bit + 1;
      bitmap = new int[initSize];
    }

    public void set(int number) {
    
    
      int index = number / bit;
      int position = number % bit;
      bitmap[index] |= 1 << (bit - 1 - position);
    }


    public boolean contains(int number) {
    
    
      int index = number / bit;
      int position = number % bit;
      return (bitmap[index] & (1 << (bit - 1 - position))) != 0;
    }
  }

  public boolean containsDuplicate(int[] nums) {
    
    
    MyBitMap map = new MyBitMap((int) 1e7);
    int min = Integer.MAX_VALUE;
    for (int num : nums) {
    
    
      min = Math.min(min, num);
    }
    for (int i = 0; i < nums.length; i++) {
    
    
      if (map.contains(nums[i] - min)) return true;
      map.set(nums[i] - min);
    }
    return false;
  }
}

猜你喜欢

转载自blog.csdn.net/qq_42007742/article/details/109310536