📫 个人主页:深夜coding算法
📣 专栏系列:2026年华为最新OD机试题库详解
🔥 一次订阅,永久解锁 | 持续更新100+篇 | 6语言全覆盖
文章目录
- ❄️前言:
- ☀️一:题目描述
- 🌙 题目名称
- 🌙 题目内容
- 🌙 输入描述
- 🌙 输出描述
- 🌙 示例
- ☀️二:解题思路
- ☀️三:代码实现
- C++
- Java
- Python3
- C语言
- JavaScript
- Go
- ☀️四:复杂度分析
- ⭐ 五:易错点
- 坑1:分配时优先地址最小
- 坑2:RELEASE 时找不到地址
- 🌻共勉:
❄️前言:
内存资源分配这题,本质是在一个固定大小的存储里,模拟分配和释放的操作。考的是对"空闲块"的管理——用数组/链表维护哪些区间还没被占,分配时找第一个够大的块给它。
☀️一:题目描述
🌙 题目名称
内存资源分配
🌙 题目内容
有一个简易的内存池,内存总大小为M字节(编号 0 到 M-1)。
支持两种操作:
REQUEST=N:申请 N 字节的连续内存,返回分配到的起始地址。优先分配地址最小的空闲块。如果没有足够大的连续空闲块,返回-1RELEASE=X:释放以地址 X 为起始的已分配内存块
🌙 输入描述
第一行:整数M,内存总大小
接下来若干行,每行一个操作,直到输入结束
🌙 输出描述
对每个REQUEST操作,输出分配的起始地址或-1
🌙 示例
输入: 100 REQUEST=10 REQUEST=20 RELEASE=0 REQUEST=8 输出: 0 10 0☀️二:解题思路
用数组mem[i]标记每个字节是否已分配。REQUEST 时扫描找连续 N 个空闲字节;RELEASE 时根据起始地址找到对应块并释放。
☀️三:代码实现
C++
#include<iostream>#include<string>#include<vector>#include<map>usingnamespacestd;intmain(){intM;cin>>M;cin.ignore();vector<bool>used(M,false);map<int,int>allocs;// start -> sizestring line;while(getline(cin,line)){if(line.rfind("REQUEST=",0)==0){intN=stoi(line.substr(8));intstart=-1;for(inti=0;i<=M-N;i++){boolok=true;for(intj=0;j<N;j++)if(used[i+j]){ok=false;break;}if(ok){start=i;break;}}if(start!=-1){for(intj=0;j<N;j++)used[start+j]=true;allocs[start]=N;}cout<<start<<endl;}elseif(line.rfind("RELEASE=",0)==0){intX=stoi(line.substr(8));if(allocs.count(X)){for(intj=0;j<allocs[X];j++)used[X+j]=false;allocs.erase(X);}}}}Java
importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intM=sc.nextInt();sc.nextLine();boolean[]used=newboolean[M];Map<Integer,Integer>allocs=newHashMap<>();while(sc.hasNextLine()){Stringline=sc.nextLine();if(line.startsWith("REQUEST=")){intN=Integer.parseInt(line.substring(8));intstart=-1;for(inti=0;i<=M-N;i++){booleanok=true;for(intj=0;j<N;j++)if(used[i+j]){ok=false;break;}if(ok){start=i;break;}}if(start!=-1){for(intj=0;j<N;j++)used[start+j]=true;allocs.put(start,N);}System.out.println(start);}elseif(line.startsWith("RELEASE=")){intX=Integer.parseInt(line.substring(8));if(allocs.containsKey(X)){for(intj=0;j<allocs.get(X);j++)used[X+j]=false;allocs.remove(X);}}}}}Python3
M=int(input())used=[False]*M allocs={}importsysforlineinsys.stdin:line=line.strip()ifline.startswith("REQUEST="):N=int(line[8:])start=-1foriinrange(M-N+1):ifnotany(used[i:i+N]):start=ibreakifstart!=-1:forjinrange(start,start+N):used[j]=Trueallocs[start]=Nprint(start)elifline.startswith("RELEASE="):X=int(line[8:])ifXinallocs:forjinrange(X,X+allocs[X]):used[j]=Falsedelallocs[X]C语言
#include<stdio.h>#include<string.h>intmain(){intM,used[1024]={0},allocs[1024]={0};scanf("%d\n",&M);charline[128];while(fgets(line,sizeof(line),stdin)){if(strncmp(line,"REQUEST=",8)==0){intN,start=-1;sscanf(line+8,"%d",&N);for(inti=0;i<=M-N;i++){intok=1;for(intj=0;j<N;j++)if(used[i+j]){ok=0;break;}if(ok){start=i;break;}}if(start!=-1){for(intj=0;j<N;j++)used[start+j]=1;allocs[start]=N;}printf("%d\n",start);}elseif(strncmp(line,"RELEASE=",8)==0){intX;sscanf(line+8,"%d",&X);if(allocs[X]){for(intj=0;j<allocs[X];j++)used[X+j]=0;allocs[X]=0;}}}}JavaScript
constinput=require('fs').readFileSync(0,'utf-8').trim().split('\n');constM=+input[0];constused=Array(M).fill(false);constallocs=newMap();for(letk=1;k<input.length;k++){constline=input[k];if(line.startsWith('REQUEST=')){constN=+line.slice(8);letstart=-1;for(leti=0;i<=M-N;i++){letok=true;for(letj=0;j<N;j++)if(used[i+j]){ok=false;break;}if(ok){start=i;break;}}if(start!==-1){for(letj=0;j<N;j++)used[start+j]=true;allocs.set(start,N);}console.log(start);}elseif(line.startsWith('RELEASE=')){constX=+line.slice(8);if(allocs.has(X)){for(letj=0;j<allocs.get(X);j++)used[X+j]=false;allocs.delete(X);}}}Go
packagemainimport("bufio";"fmt";"os";"strconv";"strings")funcmain(){scanner:=bufio.NewScanner(os.Stdin)scanner.Scan()M,_:=strconv.Atoi(scanner.Text())used:=make([]bool,M)allocs:=map[int]int{}forscanner.Scan(){line:=scanner.Text()ifstrings.HasPrefix(line,"REQUEST="){N,_:=strconv.Atoi(line[8:])start:=-1fori:=0;i<=M-N;i++{ok:=trueforj:=0;j<N;j++{ifused[i+j]{ok=false;break}}ifok{start=i;break}}ifstart!=-1{forj:=0;j<N;j++{used[start+j]=true}allocs[start]=N}fmt.Println(start)}elseifstrings.HasPrefix(line,"RELEASE="){X,_:=strconv.Atoi(line[8:])ifn,ok:=allocs[X];ok{forj:=0;j<n;j++{used[X+j]=false}delete(allocs,X)}}}}☀️四:复杂度分析
| 指标 | 数值 |
|---|---|
| 时间复杂度 | O(M * 操作数) |
| 空间复杂度 | O(M) |
⭐ 五:易错点
坑1:分配时优先地址最小
扫描时从地址 0 开始,找到第一个就停——这就是最优的。
坑2:RELEASE 时找不到地址
如果释放的地址没有对应分配记录,应忽略,不要报错。
🌻共勉:
OD机试必考模拟题,这道内存分配题学会了,类似的时间片调度、资源池管理就都能做。
📫关于本专栏:一次订阅,永久解锁全部100+篇真题详解
🔥6语言全覆盖:Java | Python3 | C++ | C语言 | JsNode | Go