华为OD机试真题——简易内存池(2025B卷:200分)Java/python/JavaScript/C++最佳实现

在这里插入图片描述

2025 B卷 200分 题型

本专栏内全部题目均提供Java、python、JavaScript、C++等多种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享

华为OD机试真题《》:


文章快捷目录

题目描述及说明

Java

python

JavaScript

C++


题目名称:


  • 知识点:内存管理(首次适应算法)、逻辑处理
  • 时间限制:1秒
  • 空间限制:256MB
  • 限定语言:不限

题目描述

请实现一个简易内存池,根据请求命令完成内存分配和释放。
内存池支持两种操作命令:REQUESTRELEASE,其格式为:

  1. REQUEST=请求的内存大小:请求分配指定大小的连续内存。
    • 若分配成功,返回分配到的内存首地址;
    • 若内存不足或请求大小为0,输出 error
  2. RELEASE=释放的内存首地址:释放指定首地址的内存块。
    • 释放成功无需输出;
    • 若释放不存在的首地址,输出 error

约束条件

  1. 内存池总大小为 100字节,地址从0开始分配。
  2. 分配必须为连续内存,优先从低地址分配。
  3. 释放后的内存可被再次分配,但已释放的内存块不可二次释放。
  4. 不会释放已分配内存块的中间地址,仅能通过首地址操作。

输入描述

  • 首行为整数 N(操作命令数,0 < N ≤ 100)。
  • 后续 N 行,每行一个操作命令,格式为 命令=参数(如 REQUEST=10)。

输出描述

  • 按顺序输出每个 REQUEST 的分配结果或 errorRELEASE 仅需在失败时输出 error

示例
输入:

5  
REQUEST=10  
REQUEST=20  
RELEASE=0  
REQUEST=20  
REQUEST=10  

输出:

0  
10  
30  
0  

说明

  1. 第一条 REQUEST=10 分配地址0~9,返回首地址0。
  2. 第二条 REQUEST=20 分配地址10~29,返回首地址10。
  3. RELEASE=0 释放首地址0的内存块,0~9变为空闲。
  4. 第三条 REQUEST=20 因0~9空间不足,从30开始分配,返回首地址30。
  5. 第四条 REQUEST=10 重新分配0~9,返回首地址0。

补充说明

  • 输入保证合法,无需处理非法参数(如负数)。
  • 同一列表元素顺序不可变,动态规划或回溯法为典型解法。

Java

问题分析

我们需要实现一个简易内存池,支持 REQUESTRELEASE 命令。内存池总大小为 100 字节,地址从 0 开始。分配时采用首次适应算法,优先低地址分配连续内存。释放时需处理合并相邻空闲块。


解题思路

  1. 数据结构设计

    • 空闲块列表:按起始地址升序排列,记录每个空闲块的起始地址和大小。
    • 已分配块字典:记录已分配块的首地址和大小,用于快速查找。
  2. REQUEST 处理

    • 遍历空闲块列表,找到第一个足够大的块。
    • 分割该块,记录已分配块,更新空闲列表。
  3. RELEASE 处理

    • 检查要释放的块是否存在。
    • 将释放的块插入空闲列表并合并相邻块。

代码实现

import java.util.*;

class Block {
   
    int start;
    int size;
    public Block(int s, int sz) {
   
        start = s;
        size = sz;
    }
}

public class Main {
   
    public static void main(String[] args) {
   
        Scanner scanner = new Scanner(System.in);
        int N = Integer.parseInt(scanner.nextLine());
        List<Block> freeList = new ArrayList<>();
        freeList.add(new Block(0, 100)); // 初始空闲块:0-99
        Map<Integer, Integer> allocated = new HashMap<>();

        for (int i = 0; i < N; i++) {
   
            String line = scanner.nextLine();
            String[] parts = line.split("=");
            String cmd = parts[0];
            int param = Integer.parseInt(parts[1]);

            if (cmd.equals("REQUEST")) {
   
                // REQUEST 处理
                int size = param;
                if (size <= 0) {
   
                    System.out.println("error");
                    continue;
                }
                boolean found = false;
                for (int j = 0; j < freeList.size(); j++) {
   
                    Block block = freeList.get(j);
                    if (block.size >= size) {
   
                        // 分配该块
                        allocated.put(block.start, size);
                        System.out.println(block.start);
                        // 处理剩余空间
                        int remaining = block.size - size;
                        if (remaining > 0) {
   
                            freeList.set(j, new Block(block.start + size, remaining));
                        } else {
   
                            freeList.remove(j);
                        }
                        found = true;
                        break;
                    }
                }
                if (!found) {
   
                    System.out.println("error");
                }
            } else if (cmd.equals("RELEASE")) {
   
                // RELEASE 处理
                int addr = param;
                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纪元A梦

再小的支持也是一种动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值