首页 > 其他分享 >第323场周赛-第三题

第323场周赛-第三题

时间:2022-12-30 21:11:08浏览次数:59  
标签:周赛 loc int mID 第三 323 allocate 数组 内存

给你一个整数 n ,表示下标从 0 开始的内存数组的大小。所有内存单元开始都是空闲的。

请你设计一个具备以下功能的内存分配器:

分配 一块大小为 size 的连续空闲内存单元并赋 id mID 。
释放 给定 id mID 对应的所有内存单元。
注意:

多个块可以被分配到同一个 mID 。
你必须释放 mID 对应的所有内存单元,即便这些内存单元被分配在不同的块中。
实现 Allocator 类:

Allocator(int n) 使用一个大小为 n 的内存数组初始化 Allocator 对象。
int allocate(int size, int mID) 找出大小为 size 个连续空闲内存单元且位于  最左侧 的块,分配并赋 id mID 。返回块的第一个下标。如果不存在这样的块,返回 -1 。
int free(int mID) 释放 id mID 对应的所有内存单元。返回释放的内存单元数目。
 

示例:

输入
["Allocator", "allocate", "allocate", "allocate", "free", "allocate", "allocate", "allocate", "free", "allocate", "free"]
[[10], [1, 1], [1, 2], [1, 3], [2], [3, 4], [1, 1], [1, 1], [1], [10, 2], [7]]
输出
[null, 0, 1, 2, 1, 3, 1, 6, 3, -1, 0]

解释
Allocator loc = new Allocator(10); // 初始化一个大小为 10 的内存数组,所有内存单元都是空闲的。
loc.allocate(1, 1); // 最左侧的块的第一个下标是 0 。内存数组变为 [1, , , , , , , , , ]。返回 0 。
loc.allocate(1, 2); // 最左侧的块的第一个下标是 1 。内存数组变为 [1,2, , , , , , , , ]。返回 1 。
loc.allocate(1, 3); // 最左侧的块的第一个下标是 2 。内存数组变为 [1,2,3, , , , , , , ]。返回 2 。
loc.free(2); // 释放 mID 为 2 的所有内存单元。内存数组变为 [1, ,3, , , , , , , ] 。返回 1 ,因为只有 1 个 mID 为 2 的内存单元。
loc.allocate(3, 4); // 最左侧的块的第一个下标是 3 。内存数组变为 [1, ,3,4,4,4, , , , ]。返回 3 。
loc.allocate(1, 1); // 最左侧的块的第一个下标是 1 。内存数组变为 [1,1,3,4,4,4, , , , ]。返回 1 。
loc.allocate(1, 1); // 最左侧的块的第一个下标是 6 。内存数组变为 [1,1,3,4,4,4,1, , , ]。返回 6 。
loc.free(1); // 释放 mID 为 1 的所有内存单元。内存数组变为 [ , ,3,4,4,4, , , , ] 。返回 3 ,因为有 3 个 mID 为 1 的内存单元。
loc.allocate(10, 2); // 无法找出长度为 10 个连续空闲内存单元的空闲块,所有返回 -1 。
loc.free(7); // 释放 mID 为 7 的所有内存单元。内存数组保持原状,因为不存在 mID 为 7 的内存单元。返回 0 。
 

提示:

1 <= n, size, mID <= 1000
最多调用 allocate 和 free 方法 1000 次

思路:用结构体存下每个mID,本题数据量较小,极限数据规模约10^6,实际考察了OS中内存管理的首次适应算法.考虑一个只包含0,1(分别代表内存的占用和空闲)的树状数组,通过检查下标为[x,y]的前缀和是否等于size来判断是否可以插入,这样可以把查找首次适应的区间从n优化为logn,但是树状数组的修改需要nlogn的时间开销,所以会在更新内存状态时性能略差,本方法在更大的数据量下会表现优异

class Allocator {
    int tree[5005] = {0};
    int maxa = 0;
    struct node//存下mID的结构体
    {
        int mid = 0;
        vector<int> a;//该mID的内存占用记录表
        node(int mid)
        {
            this->mid = mid;
        }
    };
vector<node> e;
int lowbit(int x){//树状数组模板
return x&-x;
}
void add(int x,int k)
{
    for(int i=x;i<=maxa;i+=lowbit(i))
    {
        tree[i]+=k;
    }
}
int find1(int x)
{
    int sum=0;
    for(int i=x;i;i-=lowbit(i))
    {
        sum+=tree[i];
    }
    return sum;
}
public:
    Allocator(int n) {
     maxa = n;
     for(int i =1;i<=1005;i++)//结构体初始化
     {
        e.push_back(node(i));
     }
     for(int i = 1;i<=n;i++)//初始设置内存全部空闲,用时nlogn
     {
        add(i,1);
     }
    }
    int allocate(int size, int mID) {
      int flag =-1;
      for(int i = 1;i<=maxa;i++)//循环检测大小为size为空闲区域,用时nlogn
      {
         if(find1(i+size-1)-find1(i-1)==size)
         {
            flag = i-1;
            for(int j = i;j<=i+size-1;j++)
            {
                e[mID].a.push_back(j);//存到该mID下的内存表中
                add(j,-1);//更新树状数组
            }
            break;
         }
      }
    return flag;
    }
    int free(int mID) {
    int p = e[mID].a.size();
      for(int i = 0;i<p;i++)
      {
          add(e[mID].a[i],1);//试放内存
      }
        e[mID].a.clear();//结构体清空
        return p;
    }
};

/**
 * Your Allocator object will be instantiated and called as such:
 * Allocator* obj = new Allocator(n);
 * int param_1 = obj->allocate(size,mID);
 * int param_2 = obj->free(mID);
 */

 

标签:周赛,loc,int,mID,第三,323,allocate,数组,内存
From: https://www.cnblogs.com/remarkableboy/p/17015820.html

相关文章

  • 第323场周赛-第二题
    给你一个整数数组nums。如果nums的子序列满足下述条件,则认为该子序列是一个方波:子序列的长度至少为2,并且将子序列从小到大排序之后,除第一个元素外,每个元素都是......
  • Selenium53-第三版参数化
    第二版问题和改进方案第二版问题:第二版代码中各个测试方法里有很多重复的操作步骤,没有复用,不方便代码的维护改进方案:第三版本引入参数化方式管理所有测试用例的测试数据......
  • 第三章《数组与循环》第8节:数组与循环经典例题
    利用数组和循环可以解决很多经典问题,比如对数字的查找、排列、筛选等。本小节甄选了其中一些有代表性的问题集中进行讲解,认真学习这些经典例题不仅有助于巩固Java语言的相关......
  • 全文检索工具elasticsearch:第三章: Java程序中的应用
    搭建模块创建二个项目gmall-list-service的appliction.properties:server.port=8073spring.datasource.url=jdbc:mysql://localhost:3306/gmall?characterEncoding=......
  • WordPress添加支付宝第三方登录功能
    OpenSocial操作简单适用范围广;可操作性强;无第三方平台、无接口文件冗余;功能特点社交登陆:腾讯QQ、微博、微信、豆瓣、谷歌、微软、Facebook、Twitter、Github等社交分享:QQ......
  • WordPress添加百度第三方登录功能
    OpenSocial操作简单适用范围广;可操作性强;无第三方平台、无接口文件冗余;功能特点社交登陆:腾讯QQ、微博、微信、豆瓣、谷歌、微软、Facebook、Twitter、Github等社交分享:QQ......
  • 第三方软件测试▏有效保障软件产品质量的关键性步骤
    软件测试作为软件产品生命周期中不可或缺的重要步骤,被许多软件企业所重视。主要是通过对软件产品进行全面的测试,确保软件质量以及满足用户需求。但软件测试不仅仅是个简......
  • Redis数据结构存储系统:第三章:Redis在项目中如何使用?
    简单介绍一个redis?redis是一个key-value类型的非关系型数据库,基于内存也可持久化的数据库,相对于关系型数据库(数据主要存在硬盘中),性能高,因此我们一般用redis来做缓存使用;并......
  • 第三章《数组与循环》第2节:多维数组
    ​3.1小节介绍的数组都是把数组元素从逻辑上排成一行,因此它们被称为“一维数组”。如果一个班级内有15个学生,这些学生按照身高又分成3排就坐,其排列形式如图3-2所示:3-2学生身......
  • 第三章《数组与循环》第3节:while循环
    ​在实际开发过程中,常常需要计算机完成很多重复性的工作。例如,有一个int型的数组array,它的长度为5,如果程序员希望打印出该数组的每一个元素,可以用如下代码实现:System.out.pr......