华为OD机试 - 推荐多样性(Python/JS/C/C++ 2024 E卷 100分)

news2024/9/27 7:22:31

在这里插入图片描述

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

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

推荐多样性需要从多个列表中选择元素,一次性要返回 N 屏数据(窗口数量),每屏展示 K 个元素(窗口大小),选择策略:

各个列表元素需要做穿插处理,即先从第一个列表中为每屏选择一个元素,再从第二个列表中为每屏选择一个元素,依次类推。

每个列表的元素尽量均分为 N 份,如果不够 N 份,也要全部分配完,参考样例图:

(1) 从第一个列表中选择 4 条 0123,分别放到 4 个窗口中

(2) 从第二个列表中选择 4 条 10111213,分别放到 4 个窗口中

(3) 从第三个列表中选择 4 条 20212223,分别放到 4 个窗口中

(4) 再从第一个列表中选择 4 条 4567,分别放到 4 个窗口中

(5) 再从第一个列表中选择,由于数量不足 4 条,取剩下的 2 条,放到窗口1 和窗口2

(6) 再从第二个列表中选择,由于数量不足 4 条且总的元素数达到窗口要求,取 1819 放到窗口3 和窗口4

二、输入描述

第一行输入为 N,表示需要输出的窗口数量,取值范围 [1, 10]

第二行输入为 K,表示每个窗口需要的 元素数量,取值范围 [1, 100]

之后的行数不定(行数取值范围 [1, 10]),表示每个列表输出的元素列表。元素之间以空格隔开,已经过排序处理,每个列表输出的元素数量取值范围 [1, 100]

三、输出描述

输出元素列表,元素数量 = 窗口数量 * 窗口大小,元素之间以空格分隔,多个窗口合并为一个列表输出,参考样例:

先输出窗口1的元素列表,再输出窗口2的元素列表,再输出窗口3的元素列表,最后输出窗口4的元素列表。

备注

  1. 每个列表会保证元素数量满足窗口要求,不需要考虑元素不足情况
  2. 每个列表的元素已去重,不需要考虑元素重复情况
  3. 每个列表的元素列表均不为空,不需要考虑列表为空的情况
  4. 每个列表的元素列表已经过排序处理,输出结果要保证不改变同一个列表的元素顺序
  5. 每个列表的元素数量可能是不同的

四、测试用例

测试用例1:

1、输入

4
7
0 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

2、输出

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19

3、说明

测试用例2:

1、输入

2
3
0 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

2、输出

0 10 20 1 11 21

3、说明

五、解题思路

1、问题分析

问题要求我们从多个排序好的列表中选择元素,以 “轮询” 的方式将元素分配到多个窗口中。每个窗口的展示数量固定,窗口数量也固定。主要目标是通过轮询方式选择元素,确保列表中的元素尽量平均分布到各个窗口中,同时保持列表中元素的顺序不变。

2、ArrayList + LinkedList

使用 ArrayList 存储每个输入列表,每个输入列表使用 LinkedList 来存储元素。

选择 LinkedList 的原因是它可以高效地在列表头部移除元素(removeFirst 操作的时间复杂度为 O(1)),这在轮询分配元素时非常重要。

3、具体步骤:

  1. 读取窗口数量 N 和每个窗口需要的元素数量 K。接着读取多个列表,每个列表包含已排序的整数。
  2. 使用一个二维列表来存储输入的每个列表。每个列表使用 LinkedList 以便于从列表头部快速删除元素。
  3. 创建一个一维数组 windows,大小为 N * K,用于存储所有窗口的元素。
  4. 使用一个指针 idx 表示当前正在分配元素的位置,以及一个指针 level 表示当前从哪个列表中取元素。
  5. 使用一个循环,直到所有窗口都填满:
    • 对于每一轮分配,轮询当前列表,将其前 N 个元素依次分配给 N 个窗口。
    • 如果当前列表的元素不够 N 个,或者被取空,则切换到下一个列表进行分配。
  6. 每轮次需要检查列表是否为空,如果为空则移除,以防止越界。
  7. 按照窗口的列顺序进行输出,将每个窗口的元素按列拼接成最终的结果。

主要使用了轮询遍历法。每次从当前列表中为每个窗口分配一个元素,然后切换到下一个列表。这样可以确保元素被均匀分布在各个窗口中。

4、时间复杂度

总时间复杂度为 O(N * K),其中 N 是窗口数量,K 是每个窗口的元素数量。主要耗时在于分配元素和输出结果的过程中。

六、Python算法源码

def main():
    import sys
    input = sys.stdin.read

    data = input().splitlines()
    
    # 读取窗口数量和每个窗口的元素数量
    n = int(data[0])
    k = int(data[1])

    # 读取输入的所有列表
    lists = []
    for line in data[2:]:
        if line.strip() == '':  # 本地测试时,以空行作为输入截止条件
            break
        nums = list(map(int, line.split()))
        lists.append(nums)

    # 初始化窗口矩阵为一维数组
    windows = [0] * (k * n)
    # 当前正在为窗口矩阵赋值的索引位置
    idx = 0
    # 当前从第level个列表中取值
    level = 0

    # 当窗口矩阵填满后,结束循环
    while idx < len(windows):
        # 当前轮次是否发生了"借"动作
        flag = False

        # 从当前列表中取前 n 个元素
        for i in range(n):
            windows[idx] = lists[level].pop(0)
            idx += 1

            # 如果当前列表没有元素了,则继续切到下一个列表中"借"
            if len(lists[level]) == 0 and len(lists) > 1:
                lists.pop(level)  # 删除空列表
                level %= len(lists)  # 防止越界
                flag = True  # 发生了"借"动作

        # 如果没有发生"借"动作,则切换到下一个列表
        if not flag:
            level = (level + 1) % len(lists)  # 防止越界

    # 构建输出
    result = []
    # 遍历窗口矩阵的每一列
    for j in range(n):  # 遍历列号
        for i in range(k):  # 遍历行号
            result.append(str(windows[i * n + j]))  # 将每一列的元素进行拼接

    print(' '.join(result))


if __name__ == "__main__":
    main()

七、JavaScript算法源码

function main() {
    const fs = require('fs');

    // 读取输入
    const input = fs.readFileSync('/dev/stdin', 'utf8').split('\n');
    
    // 读取窗口数量和每个窗口的元素数量
    const n = parseInt(input[0]);
    const k = parseInt(input[1]);

    // 读取输入的所有列表
    let lists = [];
    for (let i = 2; i < input.length; i++) {
        const line = input[i].trim();
        if (line === '') break; // 本地测试时,以空行作为输入截止条件
        let nums = line.split(' ').map(Number);
        lists.push(nums);
    }

    // 初始化窗口矩阵为一维数组
    let windows = new Array(k * n);
    // 当前正在为窗口矩阵赋值的索引位置
    let idx = 0;
    // 当前从第 level 个列表中取值
    let level = 0;

    // 当窗口矩阵填满后,结束循环
    while (idx < windows.length) {
        // 当前轮次是否发生了"借"动作
        let flag = false;

        // 从当前列表中取前 n 个元素
        for (let i = 0; i < n; i++) {
            windows[idx++] = lists[level].shift();

            // 如果当前列表没有元素了,则继续切到下一个列表中"借"
            if (lists[level].length === 0 && lists.length > 1) {
                lists.splice(level, 1); // 删除空列表
                level %= lists.length; // 防止越界
                flag = true; // 发生了"借"动作
            }
        }

        // 如果没有发生"借"动作,则切换到下一个列表
        if (!flag) {
            level = (level + 1) % lists.length; // 防止越界
        }
    }

    // 构建输出
    let result = [];
    // 遍历窗口矩阵的每一列
    for (let j = 0; j < n; j++) { // 遍历列号
        for (let i = 0; i < k; i++) { // 遍历行号
            result.push(windows[i * n + j]); // 将每一列的元素进行拼接
        }
    }

    console.log(result.join(' '));
}

main();

八、C算法源码

#include <stdio.h>
#include <stdlib.h>

// 辅助函数:读取一行输入
char* read_line() {
    char* line = NULL;
    size_t len = 0;
    getline(&line, &len, stdin);
    return line;
}

// 辅助函数:将字符串按空格分割并转换为整数数组
int* parse_integers(char* line, int* size) {
    int* nums = malloc(100 * sizeof(int)); // 假设每行最多有100个数字
    *size = 0;
    char* token = strtok(line, " ");
    while (token != NULL) {
        nums[(*size)++] = atoi(token);
        token = strtok(NULL, " ");
    }
    return nums;
}

int main() {
    // 读取窗口数量和每个窗口的元素数量
    int n, k;
    scanf("%d", &n);
    scanf("%d", &k);
    getchar(); // 读取换行符

    // 存储所有的列表
    int** lists = malloc(10 * sizeof(int*)); // 最多有10个列表
    int list_sizes[10] = {0};
    int list_count = 0;

    while (1) {
        char* line = read_line();
        if (line[0] == '\n' || line[0] == '\0') {
            free(line);
            break;
        }
        lists[list_count] = parse_integers(line, &list_sizes[list_count]);
        list_count++;
        free(line);
    }

    // 初始化窗口矩阵为一维数组
    int* windows = malloc(k * n * sizeof(int));
    int idx = 0;
    int level = 0;

    // 当窗口矩阵填满后,结束循环
    while (idx < k * n) {
        int flag = 0;

        for (int i = 0; i < n; i++) {
            windows[idx++] = lists[level][0];

            // 移除第一个元素
            for (int j = 0; j < list_sizes[level] - 1; j++) {
                lists[level][j] = lists[level][j + 1];
            }
            list_sizes[level]--;

            // 如果当前列表没有元素了,则继续切到下一个列表中"借"
            if (list_sizes[level] == 0 && list_count > 1) {
                free(lists[level]); // 删除空列表
                for (int j = level; j < list_count - 1; j++) {
                    lists[j] = lists[j + 1];
                    list_sizes[j] = list_sizes[j + 1];
                }
                list_count--;
                level %= list_count; // 防止越界
                flag = 1;
            }
        }

        // 如果没有发生"借"动作,则切换到下一个列表
        if (!flag) {
            level = (level + 1) % list_count; // 防止越界
        }
    }

    // 构建输出
    for (int j = 0; j < n; j++) {
        for (int i = 0; i < k; i++) {
            printf("%d ", windows[i * n + j]);
        }
    }
    printf("\n");

    // 释放内存
    free(windows);
    for (int i = 0; i < list_count; i++) {
        free(lists[i]);
    }
    free(lists);

    return 0;
}


九、C++算法源码

#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    cin.ignore(); // 读取换行符

    vector<queue<int>> lists;
    string line;

    // 读取输入的所有列表
    while (getline(cin, line)) {
        if (line.empty()) break; // 本地测试时,以空行作为输入截止条件
        istringstream iss(line);
        queue<int> q;
        int num;
        while (iss >> num) {
            q.push(num);
        }
        lists.push_back(q);
    }

    // 初始化窗口矩阵为一维数组
    vector<int> windows(k * n);
    // 当前正在为窗口矩阵赋值的索引位置
    int idx = 0;
    // 当前从第 level 个列表中取值
    int level = 0;

    // 当窗口矩阵填满后,结束循环
    while (idx < windows.size()) {
        // 当前轮次是否发生了"



🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nginx负载均衡(轮询与权重)

文章目录 1. nginx的介绍2. nginx使用场景3. nginx在windows的下载与安装4. nginx的简单使用5. nginx进行轮询测试6. nginx进行权重测试7. 总结 1. nginx的介绍 Nginx&#xff08;engine x&#xff09;是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也是一个开源的、…

PASCAL VOC数据集语义分割:解决标签值错误与数据增强不同步问题的优化方案

创作不易&#xff0c;您的打赏、关注、点赞、收藏和转发是我坚持下去的动力&#xff01; 错误原因分析&#xff1a; Assertion错误&#xff1a; 错误信息显示 Assertion t > 0 && t < n_classes failed.&#xff0c;这意味着在计算损失时&#xff0c;标签t的值不…

第四天旅游线路预览——从换乘中心到喀纳斯湖

第四天&#xff1a;从贾登峪到喀纳斯风景区入口&#xff0c;晚上住宿贾登峪&#xff1b; 换乘中心有4 路车&#xff0c;喀纳斯①号车&#xff0c;去喀纳斯湖&#xff0c;路程时长约5分钟&#xff1b; 将上面的的行程安排进行动态展示&#xff0c;具体步骤见”Google earth stu…

【devops】devops-git之github使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

继承和多态(详解)

&#x1f423;继承和多态 &#x1f31e; 继承&#x1f33b;1.引入&#x1f33b;2.访问父类成员&#x1f335;2.1 子类访问父类中的成员变量&#x1f335;2.2 子类访问父类中的成员方法 &#x1f33b;3.super关键字&#x1f33b;4.子类构造方法&#x1f33b;5.super和this&#…

java spring validation 自动、手动校验

目录 一、自动校验 第一步&#xff0c;导入依赖 第二步&#xff0c;统一异常处理 第三步&#xff0c;定义接口接收实体DTO 第四步&#xff0c;在Contoller接口中增加参数注解Validated 第五步&#xff0c;测试结果 二、手动校验 第一步&#xff0c;校验工具类 第二步&…

Protubuf入门

⼀、初识 ProtoBuf 1. 序列化概念 序列化和反序列化 序列化&#xff1a;把对象转换为字节序列的过程 称为对象的序列化。 反序列化&#xff1a;把字节序列恢复为对象的过程 称为对象的反序列化。 什么情况下需要序列化 存储数据&#xff1a;当你想把的内存中的对象状态…

Spring Boot环境下的读书笔记交流网络

第2章 技术介绍 2.1B/S架构 当向其他用户发送请求的功能时应用B/S模式具有独一无二的优点&#xff1a;用户请求通过网络向其他Web服务器发送时只需要通过浏览器就可以实现该功能。该功能的好处之一就是有效简化了客户端&#xff0c;大部分开发的软件只需要用浏览器即可&#xf…

QT Mode/View之View

目录 概念 使用已存在的视图 使用模型 使用模型的多个视图 处理元素的选择 视图间共享选择 概念 在模型/视图架构中&#xff0c;视图从模型中获取数据项并将它们呈现给用户。数据的表示方式不必与模型提供的数据表示形式相似&#xff0c;而且可能与用于存储数据项的底层数…

【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询

【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询 笛卡尔积的理解和错误笛卡尔积的理解定义例子在数据库中的应用总结 笛卡尔积的错误 正确的多表查询使用 INNER JOIN使用 WHERE 子句&#xff08;隐式内连接&#xff09; 总结 在数据库查询中&#xff0c;特别是涉及到多表…

【python计算机视觉编程——9.图像分割】

python计算机视觉编程——9.图像分割 9.图像分割9.1 图割安装Graphviz下一步&#xff1a;正文9.1.1 从图像创建图9.1.2 用户交互式分割 9.2 利用聚类进行分割9.3 变分法 9.图像分割 9.1 图割 可以选择不装Graphviz&#xff0c;因为原本觉得是要用&#xff0c;后面发现好像用不…

大模型教程:使用 Milvus、vLLM 和 Llama 3.1 搭建 RAG 应用

vLLM 是一个简单易用的 LLM 推理服务库。加州大学伯克利分校于 2024 年 7 月将 vLLM 作为孵化项目正式捐赠给 LF AI & Data Foundation 基金会。欢迎 vLLM 加入 LF AI & Data 大家庭&#xff01;&#x1f389; 在主流的 AI 应用架构中&#xff0c;大语言模型&#xff…

数据清洗-缺失值处理-缺失值可视化图(竖线)

目录 一、安装所需的python包二、缺失值可视化分析2.1 可直接运行代码2.2 以某个缺失值数据进行可视化实战2.2.1 代码运行过程截屏&#xff1a;2.2.2 缺失图可视化&#xff1a; 感觉大家对原理性的东西不太感兴趣&#xff0c;那我就直接举例提供代码&#xff0c;以及详细的注释…

13、Python如何设置文件缓冲

什么是I/O操作&#xff0c;看一下百度百科的说法&#xff1a;I/O操作是指对设备与cpu连接的接口电路的操作&#xff0c;不是对外围设备直接进行操作。宏观上讲&#xff0c;I/O是信息处理系统&#xff08;例如计算机&#xff09;与外部世界&#xff08;可能是人或其他信息处理系…

Flutter之SystemChrome全局设置

一、简介 SystemChrome作为一个全局属性&#xff0c;很像 Android 的 Application&#xff0c;功能很强大。 二、使用详解 2.1 setPreferredOrientations 设置屏幕方向 在我们日常应用中可能会需要设置横竖屏或锁定单方向屏幕等不同要求&#xff0c;通过 setPreferredOrien…

阿里云镜像报错 [Errno 14] HTTP Error 302 - Found 问题解决记录

1、问题背景和解决思路 在本地安装 CentOS7 后&#xff0c;网络已调通可正常上网&#xff0c;但切换阿里云镜像后&#xff0c;使用 yum 安装软件时出现 “[Errno 14] HTTPS Error 302 - Found Trying other mirror.” 报错&#xff0c;原因是 yum 源配置问题。给出了详细的解决…

分布式可信认证:数据安全与隐私保护新范式

文章目录 前言一、可信数字身份成数据要素流通的关键二、分布式可信认证成数据安全与隐私保护新范式1、分布式可信认证很好地解决传统数字身份认证的痛点问题2、可信数字身份上升为国家战略三、安全是未来数字身份的基础1、有效的威胁建模策略是确保这些系统安全性的基石前言 …

数据清洗-缺失值填充-随机森林搜寻最优参数填充

目录 一、安装所需的python包二、采用随机森林算法进行缺失值填充2.1可直接运行代码2.2以某个缺失值数据进行实战代码运行过程截屏&#xff1a;填充后的数据截屏&#xff1a; 三、随机森林算法 (Random Forest) 介绍3.1随机森林的定义3.2随机森林的基本思想3.3随机森林的工作原…

语言模型中的多模态链式推理(论文复现)

语言模型中的多模态链式推理&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 语言模型中的多模态链式推理&#xff08;论文复现&#xff09;简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模…

redis短信登录模型

基于Session实现登录 &#xff0c;