• 算法通关村第十五关:青铜-用4KB内存寻找重复元素


    青铜挑战-用4KB内存寻找重复元素

    位运算在查找元素中的妙用

    题目要求:
    给定一个数组,包含从1到N的整数,N最大为32000,数组可能还有重复值,且N的取值不定,若只有4KB的内存可用,该如何打印数组中所有重复元素。

    思路分析

    本题是非常典型的海量数据处理的问题,使用的是位运算结构

    内存大小关系
    1字节 = 1byte(拜特) = 1B = 8bit(比特,位)
    1KB = 1024B
    1MB = 1024KB
    1GB = 1024MB

    如果没有内存要求,创建一个大小为N的数组,然后将这些整数(32位)放进来,N最大为32000,则需要 320004B ≈ 128KB
    如果只有4KB的空间,那么只能寻址 4KB = 4*1024B = 4*1024
    8bit(比特) 该值大于32000
    因此我们可以创建32000比特的位向量(比特数组),其中一个比特位置就代表一个整数,类似索引

    利用这个位向量,就可以遍历访问整个数组。如果发现数组元素是v,那么就将位置为v的位设置为1,碰到重复元素,就输出一下

    代码实现

    1个数组元素存储 32 个数字信息,如索引为0的元素存储1~32

    def check_duplicates(array):
        bitset = [0] * (32000 // 32)
        for num in array:
            num0 = num - 1
            if (bitset[num // 32] >> (num0 % 32)) & 1:
                print(num)
            else:
                bitset[num // 32] |= (1 << (num0 % 32))
    
    
    if __name__ == '__main__':
        check_duplicates([1, 2, 3, 2])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    public class FindDuplicatesIn32000 {
        public void checkDuplicates(int[] array) {
            BitSet bs = new BitSet(32000);
            for (int i = 0; i < array.length; i++) {
                int num = array[i];
                int num0 = num - 1;
                if (bs.get(num0)) {
                    System.out.println(num);
                } else {
                    bs.set(num0);
                }
            }
    
        }
    
        static class BitSet {
            int[] bitset;
    
            public BitSet(int size) {
                this.bitset = new int[size >> 5];
            }
    
            boolean get(int pos) {
                int wordNumber = (pos >> 5);// 除以32
                int bitNumber = (pos & 0x1F); // 求32的余数
                return (bitset[wordNumber] & (1 << bitNumber)) != 0;
            }
    
            void set(int pos) {
                int wordNumber = (pos >> 5);// 除以32
                int bitNumber = (pos & 0x1F);// 求32的余数
                bitset[wordNumber] |= 1 << bitNumber;
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    事件总线及插槽
    企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图
    12月3日下午:thinkphp框架中的视图以及模型剩余部分
    离线数仓 (十) --------- 数仓环境搭建
    【电商】电商后台设计—购物车
    hinge loss的一种实现方法
    Qt之数据库:MySql驱动编译
    C++中编写没有参数和返回值的函数
    计算机毕设(附源码)JAVA-SSM基于渐进式网页应用的大众社交软件
    1、Mybatis搭建流程
  • 原文地址:https://blog.csdn.net/qq_41662142/article/details/132692010