华为OD机试 - 堆内存申请(Java 2024 D卷 100分)

在这里插入图片描述

华为OD机试 2024D卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》。

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

有一个总空间为100字节的堆,现要从中新申请一块内存,内存分配原则为:

优先分配紧接着前一块已使用的内存,分配空间足够时分配最接近申请大小的空闲内存。

二、输入描述

第1行是1个整数,表示期望申请的内存字节数。

第2到第N行是用空格分割的两个整数,表示当前已分配的内存的情况,每一行表示一块已分配的连续内存空间,每行的第1个和第2个整数分别表示偏移地址和内存块大小,如: 0 1 3 2 表示0偏移地址开始的1个字节和3偏移地址开始的2个字节已被分配,其余内存空闲。

三、输出描述

若申请成功,输出申请到内存的偏移 若申请失败,输出-1。

备注:

  1. 若输入信息不合法或无效,则申请失败
  2. 若没有足够的空间供分配,则申请失败
  3. 堆内存信息有区域重叠或有非法值等都是无效输入

四、解题思路

  1. 输入解析:
    • 第一行输入是期望申请的内存字节数。
    • 后续输入是已分配的内存块,用偏移地址和大小表示。
  2. 检查输入合法性:
    • 确保输入的内存块不重叠且偏移和大小均为有效值。
  3. 计算空闲内存块:
    • 遍历所有可能的空闲区域,计算其大小。
    • 记录每个空闲区域的起始地址和大小。
  4. 选择合适的内存块:
    • 优先选择紧接着已使用内存块后的空闲区域。
    • 如果空闲区域足够大,则选择最接近申请大小的内存块。
  5. 返回结果:
    • 如果找到合适的内存块,返回其起始地址。
    • 如果未找到合适的内存块,返回 -1。

五、Java算法源码

public class Test01 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] arr1 = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        // 读取期望申请的内存字节数
        int requestSize = arr1[0];
        // N行
        int n = arr1[1];

        // 用于存储已分配的内存块
        List<MemoryBlock> allocatedBlocks = new ArrayList<>();

        for (int i = 0; i < n; i++) {
            int[] arr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
            int start = arr[0];
            int size = arr[1];
            allocatedBlocks.add(new MemoryBlock(start, size));
        }

        // 对已分配的内存块进行排序,按照偏移地址排序
        allocatedBlocks.sort(Comparator.comparingInt(block -> block.start));

        // 计算空闲内存块
        List<MemoryBlock> freeBlocks = calculateFreeBlocks(allocatedBlocks, 100);

        // 找到最合适的空闲块
        int allocationStart = findSuitableBlock(freeBlocks, requestSize);

        // 输出结果
        System.out.println(allocationStart);
    }

    // 内存块类,用于存储起始地址和大小
    static class MemoryBlock {
        int start;
        int size;

        MemoryBlock(int start, int size) {
            this.start = start;
            this.size = size;
        }
    }

    // 计算空闲内存块
    private static List<MemoryBlock> calculateFreeBlocks(List<MemoryBlock> allocatedBlocks, int totalSize) {
        List<MemoryBlock> freeBlocks = new ArrayList<>();

        // 检查起始位置是否有空闲块
        if (allocatedBlocks.isEmpty() || allocatedBlocks.get(0).start > 0) {
            int end = allocatedBlocks.isEmpty() ? totalSize : allocatedBlocks.get(0).start;
            freeBlocks.add(new MemoryBlock(0, end));
        }

        // 检查已分配块之间的空闲区域
        for (int i = 0; i < allocatedBlocks.size() - 1; i++) {
            int endCurrent = allocatedBlocks.get(i).start + allocatedBlocks.get(i).size;
            int startNext = allocatedBlocks.get(i + 1).start;
            if (startNext > endCurrent) {
                freeBlocks.add(new MemoryBlock(endCurrent, startNext - endCurrent));
            }
        }

        // 检查最后一个已分配块后面的空闲区域
        if (!allocatedBlocks.isEmpty()) {
            int endLast = allocatedBlocks.get(allocatedBlocks.size() - 1).start + allocatedBlocks.get(allocatedBlocks.size() - 1).size;
            if (endLast < totalSize) {
                freeBlocks.add(new MemoryBlock(endLast, totalSize - endLast));
            }
        }

        return freeBlocks;
    }

    // 找到最合适的空闲块
    private static int findSuitableBlock(List<MemoryBlock> freeBlocks, int requestSize) {
        MemoryBlock bestFit = null;

        for (MemoryBlock block : freeBlocks) {
            if (block.size >= requestSize) {
                if (bestFit == null || block.size < bestFit.size) {
                    bestFit = block;
                }
            }
        }

        return (bestFit != null) ? bestFit.start : -1;
    }
}

六、效果展示

1、输入

1 2
0 1
3 2

2、输出

1

3、说明

堆中已使用的两块内存是偏移从0开始的1字节和偏移从3开始的2字节,空闲的两块内存是偏移从1开始2个字节和偏移从5开始95字节根据分配原则,新申请的内存应从1开始分配1个字节,所以输出偏移为1。

在这里插入图片描述


🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 C卷 200分)

🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/796442.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VMware安装Ubuntu以及利用vscode远程Ubuntu

一、VMware安装Ubuntu &#xff08;1&#xff09;VMware安装Ubuntu主要参考此文VMware虚拟机安装Ubuntu22.04图文教程&#xff08;超详细&#xff01;&#xff01;&#xff01;&#xff09;。 &#xff08;2&#xff09;VMware密钥参考此文24年VMware 17密钥(附下载链接&#…

【经典面试题】是否形成有环链表

1.环形链表oj 2. oj解法 利用快慢指针&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/typedef struct ListNode ListNode; bool hasCycle(struct ListNode *head) {ListNode* slow head, *fast…

M J更改图像生成方式的参数选项

一个完整的/imagine命令可能包含几个内容,例如图像 URL、图像权重、算法版本和其他开关。 /imagine参数应遵循以下顺序: /imagine prompt: https://example/tulip.jpg a field of tulips in the style of Mary Blair --no farms --iw .5 --ar 3:2 在这种情况下,“开关”是指…

SpringBoot使用Redisson操作Redis及使用场景实战

前言 在SpringBoot使用RedisTemplate、StringRedisTemplate操作Redis中&#xff0c;我们介绍了RedisTemplate以及如何SpringBoot如何通过RedisTemplate、StringRedisTemplate操作Redis。 RedisTemplate的好处就是基于SpringBoot自动装配的原理&#xff0c;使得整合redis时比较…

论文AIGC率需降低?降AI率工具,快速有效

当论文借助AI撰写时&#xff0c;难免会留下AI的痕迹&#xff1b;若未经处理直接提交给导师&#xff0c;很可能会遭到批评。因此&#xff0c;去除AI痕迹成为了关键的一环。幸运的是&#xff0c;笔灵去ai痕迹提供了去AI痕迹的功能&#xff0c;极大地简化了这一过程。用户仅需一键…

如何通过博客获得独立站外链?

通过博客获取独立站外链是一种非常有效的策略&#xff0c;其中GPB外链尤为出色&#xff0c;在多种外链的形式中&#xff0c;博客外链本身就是最好的外链 而想通过博客来获取高质量的独立站外链&#xff0c;创建高质量的内容是关键&#xff0c;无论是谷歌还是用户&#xff0c;对…

mts怎么改成mp4?介绍四个将mts改成MP4的方法

mts怎么改成mp4&#xff1f;当你需要将mts文件转换为MP4格式时&#xff0c;你可以采取一些简单的方法来完成这个任务。mts是一种视频文件格式&#xff0c;通常用于高清摄像机录制的视频&#xff0c;而MP4是一种通用且流行的视频格式&#xff0c;几乎在所有设备和平台上都得到支…

DockerCompose拉取DockerHub镜像,并部署OpenMetaData

参考博主&#xff1a;http://t.csdnimg.cn/i49ET 一、DockerCompose拉取DockerHub镜像 方法一&#xff08;不太行&#xff09;&#xff1a; 在daemon.json文件中添加一些国内还在服务的镜像站&#xff08;可能某些镜像会没有&#xff09; ([ -f /etc/docker/daemon.json ] ||…

数据结构之单链表(赋源码)

数据结构之单链表 线性表 线性表的顺序存储结构&#xff0c;有着较大的缺陷 插入和删除操作需要移动大量元素。会耗费很多时间增容需要申请空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不小的消耗即使是使用合理的增容策略&#xff0c;实际上还会浪费许多用不上的…

语言模型演进:从NLP到LLM的跨越之旅

在人工智能的浩瀚宇宙中&#xff0c;自然语言处理&#xff08;NLP&#xff09;一直是一个充满挑战和机遇的领域。随着技术的发展&#xff0c;我们见证了从传统规则到统计机器学习&#xff0c;再到深度学习和预训练模型的演进。如今&#xff0c;我们站在了大型语言模型&#xff…

木舟0基础学习Java的第十六天(异常,分类,自定义异常,注意事项)

异常 异常概述&#xff1a;异常是Java程序运行过程中出现的错误 异常分类&#xff1a;API查找Throwable 1.Error(服务器宕机&#xff0c;数据库崩溃等) 2.Exception C(异常的继承体系)API查RuntimeException 运行时异常&#xff1a;一般是程序员的错误异常可以让我们发现错…

C#实现最短路径算法

创建点集 double r 200 * 500;double width 1920;double height 1080;int col (int)(r / width);int row (int)(r / height);List<(double, double)> list1 new List<(double, double)>();for (int i 0; i < row; i){var y i * height;if (y < r){va…

青年发展型城市成新青择地,期待与挑战并存

随着社会的发展和城市化进程的加快&#xff0c;青年人在选择未来定居地时面临着越来越多的选择。近日&#xff0c;中国青年报社社会调查中心联合问卷网对1500名青年进行的一项调查显示&#xff0c;74.8%的受访青年表示会优先考虑青年发展型城市。那么&#xff0c;青年在选择未来…

编程范式之并发编程

目录 前言1. 并发编程的定义2. 并发编程的特点2.1 任务交替执行2.2 状态共享与同步2.3 并行执行 3. 并发编程的适用场景3.1 高性能计算3.2 I/O 密集型应用3.3 实时系统 4. 并发编程的优点4.1 提高资源利用率4.2 缩短响应时间4.3 提高系统吞吐量 5. 并发编程的缺点5.1 编程复杂性…

gpt-4o看图说话-根据图片回答问题

问题&#xff1a;中国的人口老龄化究竟有多严重&#xff1f; 代码下实现如下&#xff1a;&#xff08;直接调用openai的chat接口&#xff09; import os import base64 import requests def encode_image(image_path): """ 对图片文件进行 Base64 编码 输入…

微分方程建模

微分方程建模是数学建模的重要方法&#xff0c;因为许多实际问题的数学描述将导致求解微分方程的定解问题。在高教杯数学建模竞赛中每年都会有一道微分方程建模问题&#xff0c;大体上可以按以 下几步&#xff1a; 1. 根据实际要求确定要研究的量(自变量、未知函数、必要的参数…

【Linux信号】阻塞信号、信号在内核中的表示、信号集操作函数、sigprocmask、sigpending

我们先来了解一下关于信号的一些常见概念&#xff1a; 实际执行 信号的处理动作 称为信号递达。 信号从产生到递达的之间的状态称为信号未决。 进程可以选择阻塞(Block)某个信号。 被阻塞的信号产生时是处于未决状态的&#xff0c;知道进程解除对该信号的阻塞&#xff0c;该…

基于颜色模型和边缘检测的火焰识别FPGA实现,包含testbench和matlab验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 将FPGA仿真结果导入到matlab显示结果&#xff1a; 测试样本1 测试样本2 测试样本3 2.算法运行软件版本 vivado2019.2 …

鸿蒙HarmonyOS应用开发为何选择ArkTS不是Java?

前言 随着智能设备的快速发展&#xff0c;操作系统的需求也变得越来越多样化。为了满足不同设备的需求&#xff0c;华为推出了鸿蒙HarmonyOS。 与传统的操作系统不同&#xff0c;HarmonyOS采用了一种新的开发语言——ArkTS。 但是&#xff0c;刚推出鸿蒙系统的时候&#xff0…

MySQL数据库课程设计——订餐系统(MySQL数据库+Qt5用户界面+python)

目录 一、系统定义 二、需求分析 三、系统设计 四、详细设计 五、参考文献 一、系统定义 订餐系统是一种基于网络技术的在线点餐平台&#xff0c;旨在为用户提供方便快捷的订餐服务。该系统主要包括用户登录、用户管理、菜单管理、订单管理、支付管理、评价管理等功能模块…