2024年华为9月4日秋招笔试真题题解

2024年华为0904秋招笔试真题

    • 二叉树消消乐
    • 好友推荐系统
    • 维修工
      • 力扣上类似的题--K站中转内最便宜的航班

二叉树消消乐

题目描述

给定原始二叉树和参照二叉树(输入的二叉树均为满二叉树,二叉树节点的值范围为[1,1000],二叉树的深度不超过1000),现对原始二叉树和参照二叉树中相同层级目值相同的节点进行消除、消除规则为原始叉树和参照二叉树中存在多个值相同的节点只能消除等数量的、消除后的节点变为无效节点,请按节点值出现频率从高到低输出消除后原始二叉树中有效节点的值(如果原始二叉树消除后没有有效节点返回0)。

输入描述

原始二叉树中的节点个数
原始二叉树
参照二叉树中的节点个数
参照二叉树

输出描述

原始二叉树中有效节点的值,按出现频率从高到低排序(相同频率的值按大小排序),相同频率的值按降序排列。

用例输入

7
1 3 3 3 4 5 6
3
2 3 4

用例输出

36541

样例1解释:
原始二叉树A消除参照二叉树B中的重复元素后,有效节点剩余2个3,1个6,1个5,1个4,1个1,3出现的频率2,6、5、4、1出现的频率为1,按值从大到小排序、所以排序结果为36541。

求解思路

注意审题,题目明确指出这是一个满二叉树,因此我们不需要真的去构建一个二叉树,只需要利用满二叉树的性质去进行模拟求解就行。

需要注意的是,华为的命题人在写题面时候不够严谨,题面说二叉树的深度不超过1000,这显然是不现实的,毕竟这是满二叉树,如果深度达到几十上百的话,二叉树的节点数直接2的几百次方,显然这么大的数据哪怕O(n)的时间复杂度也过不了。因此只需要按照节点数为1e5的规模来设计算法即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100001;
int n, m;
int origin[maxn], refer[maxn];
vector<int>sum(maxn, 0);

void dfs(int depth) {
    int start = pow(2, depth - 1), end = start + pow(2, depth - 1);
    if(start > n || start > m) return;
    map<int, int>mp1, mp2;
    for(int i = start; i < end; i++) {
        mp1[origin[i]]++;
        mp2[refer[i]]++;
    }
    for(auto i : mp1) {
        if(mp2[i.first] > i.second) sum[i.first] -= i.second;
        else sum[i.first] -= mp2[i.first];
        // cout << i.first << " " << sum[i.first] << endl;
    }
    dfs(depth + 1);
}

bool cmp(pair<int, int>a, pair<int, int> b) {
    if(a.second != b.second) return a.second > b.second;
    return a.first > b.first;
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &origin[i]);
        sum[origin[i]]++;
    }
    scanf("%d", &m);
    for(int i = 1; i <= m; i++) scanf("%d", &refer[i]);

    dfs(1);

    // for(int i = 1; i <= n; i++) cout << sum[origin[i]] << " ";
    // cout << endl;

    vector<pair<int, int>>v;
    set<int>s;
    for(int i = 1; i <= n; i++) s.insert(origin[i]);
    for(auto i : s) v.push_back(make_pair(i, sum[i]));

    // for(auto i : s) cout << i << " " << sum[i] << " " << endl;

    sort(v.begin(), v.end(), cmp);
    bool flag = false;
    for(auto i : v) {
        if(i.second != 0) {
            flag = true;
            printf("%d", i.first);
        } 
        else break;
    }
    if(!flag) printf("0");

    return 0;
}
/*
15
5 8 8 8 7 7 7 6 6 9 9 7 7 5 6
7
5 6 6 7 7 8 8
*/

好友推荐系统

题目描述

你正在为一个社交网络平台开发好友推荐功能。

平台上有N个用户(每个用户使用1到N的整数编号),同时系统中维护了用户之间的好友关系。

为了推荐新朋友,平台决定采用“共同好友数量"作为衡量两个用户之间相似度的标准。

系统根据输入用户编号K,输出与此用户K相似度最高的前L个用户ID来推荐给用户K。

相似度定义:两个用户非好友,两个用户的相似度为拥有的共同好友数(例如用户A和用户B,只有共同好友C和D,相似度=2)

输入描述

第一行包含四个整数 N,M 、K和L,分别表示用户的数量(N),好友记录条数(M)、查询的用户编号(K)和推荐的好友数量(L)。接下来 M 行,每行包含两个整数编号X和Y,表示编号为X和Y用户是好友。

  1. 输入格式都是标准的,无需考虑输出异常场景(不会包含用户和自己是好友的输入,例如11)

  2. 用户数不超过1024,用户编码最大1024

  3. 好友记录数不超过10240

输出描述

根据输入K和L,输出和用户K相似度最高的L个用户编码。

  1. 输出相似度最高的前L个用户编码,按照相似度从高到低排序

  2. 如果有相似度相同的可能好友,按照用户编号从小到大排序

  3. 如果推荐的好友个效不足L个,则推荐与用户K无无共同好友关系的用户(陌生人)作为可能好友,如果推荐仍不满足L个用户,剩余推荐用户编码使用0来占位

用例输入

6 7 3 2
1 2
1 3
2 3
3 4
3 5
4 5
5 6

用例输出

6 0

输入包含了6个用户,7条好友记录,给用户ID编号为3的用户推荐2个好友。

输出只有编号为6的用户可能是编号3用户的可能好友;

尝试推荐与编号3用户无共同好友的其他用户,由于除编号为6的用户之外,其他用户和编号3用户都是好友,所以找不到陌生人作为推荐的第二个用户;

推荐结果不足2个用户,所以推荐的第二个用户编码使用0来占位补足。

求解思路

我们首先可以利用哈希表构建用户之间的好友关系,方便在O(1)的时间复杂度内查找两个用户之间是否是好友关系

然后排序遍历就可以得到推荐列表了

#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b) {
    if(a.second != b.second) return a.second > b.second;
    return a.first < b.first;
}
int main() {
    int N, M, K, L;
    scanf("%d %d %d %d", &N, &M, &K, &L);
    int x, y;
    int isf[1025][1025] = {0};
    for(int i = 0; i < M; i++) {
        scanf("%d%d", &x, &y);
        isf[x][y] = isf[y][x] = 1;
    }

    vector < pair<int, int> > sim;

    for(int i = 1; i <= N; i++) {
        if(i == K) continue;
        if(isf[K][i] != 1) {
            int cnt = 0;
            for(int j = 1; j <= N; j++) {
                if(i == j) continue;
                if(isf[K][j] == 1 && isf[i][j] == 1) cnt++;
            }
            sim.push_back(make_pair(i, cnt));
        }
    }

    sort(sim.begin(), sim.end(), cmp);
    int sum = 0;
    for(auto i : sim) {
        printf("%d ", i.first);
        sum++;
    }
    if(sum < L) {
        for(int i = sum; i < L; i++) printf("0 ");
    }

    return 0;
}

维修工

题目描述

维修工要给n个客户更换设备,为每个用户更换一个设备。维修工背包内最多装k个设备,如果背包里有设备可以直接前往下一个客户更换或回公司补充设备,没有则需要回公司取设备。这些客户有优先级,维修工需要按照优先级给客户更换设备,优先级level用数字表示,数字小的优先级高。维修工从公司出发,给n个客户更换设备,最后再返回公司。请计算维修工完成这项工作所需要经历的最短总距离是多少。维修工可以走斜线。

输入描述

第一行两个正整数 n,k(1≤k≤n≤2000),表示客户数和维修工背包容量。
第二行两个正整数 x,y ,用空格分隔(1 ≤ x , y ≤ 10^6),表示公司的坐标
接下来n行每行三个正整数 x i x_i xi, y i y_i yi, l e v e l i level_i leveli,用空格分隔(1≤ x i x_i xi, y i y_i yi≤10^6,1≤ l e v e l i level_i leveli<=n)。
( x i x_i xi, y i y_i yi)表示第i个客户的位置坐标, l e v e l i level_i leveli表示第 i i i个客户的优先级,保证所有客户优先级不同,客户和公司坐标不会重叠。

输出描述

输出最短总距离,结果四舍五入并保留一位小数,例如:9.0。

用例输入

3 2
1 1
3 1 1
1 2 2
3 2 3

用例输出

9.2

样例1解释:

从(1,1)->(3,1)->(1,1)->(1,2)->(3,2)->(1,1) = 2+2+1+2+√5 = 9.236

求解思路

题目的意思是维修工在维修完一家客户后,就会废掉背包内的一个设备(题面没讲清楚,一开始理解了好久背包内有设备为什么需要回公司取)。

因为本题规定了客户的优先级,因此我们首先将客户按照优先级进行排序。

接下来,我们可以按照记忆化搜索的方法,决定维修完当前客户后,到底回公司取设备再前往下一家客户还是直接去下一家客户维修。

我们采用memo数组记录每次的结果

memo[i + 1][k - 1] 表示回公司取完设备再前往下一家客户维修

memo[i + 1][j - 1] 表示背包内还有设备,直接前往下一家客户维修

#include<bits/stdc++.h>
using namespace std;

double cal_dis(int x1, int y1, int x2, int y2) {
    return (double)sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
}

const int maxn = 2001;
int n, k, cx, cy;

struct customer
{
    int x, y, level;
    bool operator < (const customer& other) const { 
        return level < other.level; 
    }
}p[maxn];

/*
记忆化搜索,假设memo[i][j]表示维修完第i个客户,并且背包中还剩下j个设备。
*/
vector <vector<double>> memo(maxn, vector<double>(maxn, 0)); 

double dfs(int i, int j) {
    if(memo[i][j] > 0) return memo[i][j];
    double dis = cal_dis(p[i].x, p[i].y, cx, cy);
    double ans = 99999999999.0;
    if(i < n - 1) {
        ans = min(ans, dfs(i + 1, k - 1) + dis + cal_dis(p[i + 1]. x, p[i + 1].y, cx, cy));
        // cout << dis + cal_dis(p[i + 1]. x, p[i + 1].y, cx, cy) << endl;
        if(j > 0) {
            ans = min(ans, dfs(i + 1, j - 1) + cal_dis(p[i + 1].x, p[i + 1].y, p[i].x, p[i].y));
            // cout <<  cal_dis(p[i + 1].x, p[i + 1].y, p[i].x, p[i].y) << endl;
        }
    } else { // 如果是最后一家,则修完直接回公司
        ans = dis;
    }
    return memo[i][j] = ans;
}

int main() {
    scanf("%d%d", &n, &k);
    scanf("%d%d", &cx, &cy);
    for(int i = 0; i < n; i++) scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].level);
    sort(p, p + n);

    dfs(0, k);

    double ans = dfs(0, k - 1) + cal_dis(p[0].x, p[0].y, cx, cy);
    printf("%.1f", ans);

    return 0;
}

维修工这个题是通过记忆化搜索求解最短路径的问题,想起之前在力扣上面刷到一个类似的题目,K站中转内最便宜的航班

题目链接

力扣上类似的题–K站中转内最便宜的航班

题目描述

n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线,使得从 srcdst价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1

image-20240912141710328

image-20240912141914144

求解思路

和维修工一样,我们只需要利用记忆化搜索去寻找到第k个城市所需要的最少花费即可,注意k次中转的限制。

class Solution {
public:
    const int INF = 99999999;
    /*
    dp[i][j] 表示起点到城市i到达第j个城市的最少花费
    */
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
        vector <int> G[n]; // 构建邻接矩阵
        vector <vector<int>> price(n, vector<int>(n, INF));
        for(auto flight : flights) {
            G[flight[0]].push_back(flight[1]); 
            price[flight[0]][flight[1]] = flight[2];
        }

        vector <vector<int>> dp(n, vector<int>(k + 2, 0));

        function<int(int, int)> dfs = [&](int i, int j) {
            if(dp[i][j] > 0) return dp[i][j];
            if(i == dst) {
                if(j <= k + 1) return dp[i][j];
                return INF;
            }
            int ans = INF;
            for(auto v : G[i]) {
                if(j < k + 1)
                    ans = min(ans, dfs(v, j + 1) + price[i][v]);
            }
            return dp[i][j] = ans;
        };

        int ans = dfs(src, 0);
        return ans == INF ? -1 : ans;
    }
};

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

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

相关文章

Maven 解析:打造高效、可靠的软件工程

Apache Maven【简称maven】 是一个用于 Java 项目的构建自动化工具&#xff0c; 通过提供一组规则来管理项目的构建、依赖关系和文档。 1.Pre-预备知识&#xff1a; 1.1.Maven是什么&#xff1f; [by Maven是什么&#xff1f;有什么作用&#xff1f;Maven的核心内容简述_ma…

简化登录流程,助力应用建立用户体系

随着智能手机和移动应用的普及&#xff0c;用户需要在不同的应用中注册和登录账号&#xff0c;传统的账号注册和登录流程需要用户输入用户名和密码&#xff0c;这不仅繁琐而且容易造成用户流失。 华为账号服务(Account Kit)提供简单、快速、安全的登录功能&#xff0c;让用户快…

Zabbix自定义监控项与触发器

当我们需要获取某台主机上的数据时&#xff0c;直接利用 zabbix 提供的模板可以很方便的获得需要的数据,但是有些特别的数据&#xff0c;利用这些现有的模板或监控项是无法实现的&#xff0c;例如网站状态信息的监控、mysql数据库主从状态等信息。这是就需要自己定义键值和监控…

Java许可政策再变,Oracle JDK 17 免费期将结束!

原文地址&#xff1a;https://www.infoworld.com/article/3478122/get-ready-for-more-java-licensing-changes.html Oracle JDK 17的许可协议将于9月变更回Oracle Technology Network License Agreement&#xff0c;这将迫使用户重新评估他们的使用策略。 有句老话说&#xf…

小程序组件间通信

文章目录 父传子子传父获取组件实例兄弟通信 父传子 知识点&#xff1a; 父组件如果需要向子组件传递指定属性的数据&#xff0c;在 WXML 中需要使用数据绑定的方式 与普通的 WXML 模板类似&#xff0c;使用数据绑定&#xff0c;这样就可以向子组件的属性传递动态数据。 父…

java实际开发——数据库存储金额时用什么数据类型?(MySQL、PostgreSQL)

目录 java开发时金额用的数据类型——BigDecimal MySQL存储金额数据时用的数据类型是——decimal PostgreSQL存储金额数据时用的数据类型是——decimal 或 money java开发时金额用的数据类型——BigDecimal https://blog.csdn.net/Jilit_jilit/article/details/142180903?…

YOLOv5/v8 + 双目相机测距

yolov5/v8双目相机测距的代码&#xff0c;需要相机标定 可以训练自己的模型并检测测距&#xff0c;都是python代码 已多次实验&#xff0c;代码无报错。 非常适合做类似的双目课题&#xff01; 相机用的是汇博视捷的双目相机&#xff0c;具体型号见下图。 用的yolov5是6.1版本的…

ubuntu2204安装kvm

ubuntu2204安装kvm 前言一、检测硬件是否支持二、安装软件三、创建/管理虚拟机1、创建存储池2、qemu创建镜像3、xml文件运行虚拟机1、范文2、xml文件创建虚机3、创建虚机 4、克隆虚机5、创建快照6、脚本创建VNC连接 四、创建集群1、安装glusterfs2、加入集群删除节点 3、 创建卷…

深度剖析iOS渲染

iOS App 图形图像渲染的基本流程&#xff1a; 1.CPU&#xff1a;完成对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制。 2.GPU&#xff1a;GPU拿到CPU计算好的显示内容&#xff0c;完成纹理的渲染&#xff0c; 渲染完成后将渲…

基于YOLO深度学习和百度AI接口的手势识别与控制项目

基于YOLO深度学习和百度AI接口的手势识别与控制项目 项目描述 本项目旨在开发一个手势识别与控制系统&#xff0c;该系统能够通过摄像头捕捉用户的手势&#xff0c;并通过YOLO深度学习模型或调用百度AI接口进行手势识别。识别到的手势可以用来控制计算机界面的操作&#xff0…

使用 Elastic 和 LM Studio 的 Herding Llama 3.1

作者&#xff1a;来自 Elastic Charles Davison, Julian Khalifa 最新的 LM Studio 0.3 更新使 Elastic 的安全 AI Assistant 能够更轻松、更快速地与 LM Studio 托管模型一起运行。在这篇博客中&#xff0c;Elastic 和 LM Studio 团队将向你展示如何在几分钟内开始使用。如果你…

API - String 和 ArrayList

01 API是什么 答&#xff1a;API 全称 Application Programming Interfaace 应用程序编程接口。就是别人写好的一些程序&#xff0c;我们可以使用它们去解决相关问题。 02 为什么要学API 答&#xff1a;不要重复造轮子。Java已经有20多年的历史了&#xff0c;在这20多年里Ja…

图新地球-将地图上大量的地标点批量输出坐标到csv文件【kml转excel】

0.序 有很多用户需要在卫星影像、或者无人机航测影像、倾斜模型上去标记一些地物的位置&#xff08;如电线杆塔、重点单位、下水盖等&#xff09; 标记的位置最终又需要提交坐标文本文件给上级单位或者其他部门使用&#xff0c;甚至需要转为平面直角坐标。 本文的重点是通过of…

【C++】模板进阶:深入解析模板特化

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与Queue 本章将…

加密与安全_优雅存储用户密码的最佳实践

文章目录 Pre概述最佳实践避免使用MD5、SHA1等快速哈希算法加盐哈希 &#xff08;不推荐&#xff09;使用BCrypt、Argon2等慢哈希算法 (推荐)BCrypt Code1. 自动生成和嵌入盐2. 哈希结果的格式3. 代价因子 BCrypt特点 防止暴力破解1. 登录失败锁定2. 双因素认证&#xff08;2FA…

Java应用压测工具JMeter

目录 1、下载JMeter 2、配置环境变量 3、配置语音 4、使用 1、下载JMeter Apache JMeter - Apache JMeter™ 千万别下载这个&#xff0c;会报错、 千万别下载这个&#xff0c;会报错、 千万别下载这个&#xff0c;会报错 下载这个&#xff0c;失败多下载几次 2、配置环…

react 高阶组件

概述 高级组件到底能够解决什么问题&#xff1f;举一个特别简单的例子&#xff0c;话说小明负责开发一个 web 应用&#xff0c;应用的结构如下所示&#xff0c;而且这个功能小明已经开发完了。 但是&#xff0c;有一天老板突然提出了一个权限隔离的需求&#xff0c;就是部分模…

自动下载网易云音乐歌手全部歌曲工具

自动下载网易云音乐歌手全部歌曲工具 使用说明 下载 地址 运行 双击运行对应版本文件 开发 安装依赖&#xff0c;运行 yarn yarn start打包 yarn pkg

实习期间git的分枝管理以及最常用的命令

各位找工作实习的友友在工作之前一定要把git的相关知识掌握呀&#xff0c;我实现期间被leader说过关于git规范的相关问题了 目前已更新系列&#xff1a; 当前&#xff1a;:实习期间git的分枝管理以及最常用的命令 Redis高级-----持久化AOF、RDB原理 Redis高级---面试总结5种…

python绘制3d建筑

import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d.art3d import Poly3DCollection# 随机生成建筑块数据 def generate_building_blocks(num_blocks, grid_size100, height_range(5, 50), base_size_range(10, 30)):buildings []for _ in range(…