华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
给定一个 单链表 L,请编写程序输出 L 中间结点保存的数据。
如果有两个中间结点,则输出其中第二个中间结点保存的数据。
例如:
给定 L 为 1→7→5,则输出应该为 7;
给定 L 为 1→2→3→4,则输出应该为 3。
二、输入描述
每个输入包含 1 个 测试用例。每个测试用例:
第一行给出链表首结点的地址L。结点总个数正整数 N(≤105)。
结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address 是结点地址,Data 是结点保存的整数数据 (0 ≤ Data ≤ 108),Next 是下一个结点的地址。
三、输出描述
对每个测试用例,在一行中输出 L 中间结点保存的数据。
如果有两个中间结点,则输出其中第二个中间结点保存的数据。
(如果多个节点取中间值相同,偶数个取偏右边的那个)
四、测试用例
测试用例1:
1、输入
00010 4
00000 3 -1
00010 5 12309
11451 6 00000
12309 7 11451
2、输出
6
3、说明
链表为 00010→12309→11451→00000,数据为 5→7→6→3,中间结点为 7 和 6,选择第二个中间结点 6。
测试用例2:
1、输入
10000 3
76892 7 12309
12309 5 -1
10000 1 76892
2、输出
7
3、说明
链表为 10000→76892→12309,数据为 1→7→5,中间结点为 7。
五、解题思路
- 输入处理:
- 首先读取链表的首结点地址和结点总数。
- 接着读取每个结点的详细信息(地址、数据、下一个结点的地址)。
- 使用 HashMap 将每个地址映射到其对应的结点数据和下一个结点的地址,以便快速访问。
- 链表遍历:
- 从首结点地址开始,按照 Next 地址依次遍历链表,并将结点的数据存入一个 ArrayList 中。
- 这样,我们可以得到链表中所有结点的数据按顺序排列。
- 寻找中间结点:
- 根据链表的长度,计算中间结点的位置。
- 如果链表长度为奇数,则中间结点为 (length / 2)。
- 如果链表长度为偶数,则中间结点为 (length / 2)(即偏右的那个结点)。
- 输出结果:
- 输出计算得到的中间结点的数据。
六、Python算法源码
# Python 版本
import sys
def main():
# 读取标准输入的所有行
lines = sys.stdin.read().splitlines()
if not lines:
return
# 第一行包含首结点地址和结点总数
head_address, N = lines[0].split()
N = int(N)
# 创建一个字典来存储地址到结点数据和下一个地址的映射
node_map = {}
for i in range(1, N + 1):
parts = lines[i].split()
address = parts[0]
data = int(parts[1])
next_addr = parts[2]
node_map[address] = (data, next_addr)
# 遍历链表,按照顺序存储结点的数据
data_list = []
current = head_address
while current != "-1":
if current not in node_map:
break # 如果地址不存在,结束遍历
data, next_addr = node_map[current]
data_list.append(data)
current = next_addr
# 计算中间结点的位置
if not data_list:
print()
else:
mid = len(data_list) // 2
print(data_list[mid])
if __name__ == "__main__":
main()
七、JavaScript算法源码
// JavaScript 版本
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let inputLines = [];
rl.on('line', function(line) {
inputLines.push(line);
}).on('close', function() {
// 第一行包含首结点地址和结点总数
const firstLine = inputLines[0].split(' ');
const headAddress = firstLine[0];
const N = parseInt(firstLine[1]);
// 创建一个Map来存储地址到结点数据和下一个地址的映射
const nodeMap = new Map();
for(let i=1; i<=N; i++) {
const parts = inputLines[i].split(' ');
const address = parts[0];
const data = parseInt(parts[1]);
const nextAddr = parts[2];
nodeMap.set(address, {data: data, next: nextAddr});
}
// 遍历链表,按照顺序存储结点的数据
const dataList = [];
let current = headAddress;
while(current !== "-1") {
if(!nodeMap.has(current)) break; // 如果地址不存在,结束遍历
const node = nodeMap.get(current);
dataList.push(node.data);
current = node.next;
}
// 计算中间结点的位置
if(dataList.length === 0){
console.log('');
}
else{
const mid = Math.floor(dataList.length / 2);
console.log(dataList[mid]);
}
});
八、C算法源码
/* C 版本 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 定义结点结构体
typedef struct Node {
char address[6]; // 5位地址加终止符
int data;
char next[6];
} Node;
int main(){
char head_address[6];
int N;
// 读取首结点地址和结点总数
scanf("%s %d", head_address, &N);
// 创建一个数组存储所有结点
Node nodes[N];
for(int i=0; i<N; i++){
scanf("%s %d %s", nodes[i].address, &nodes[i].data, nodes[i].next);
}
// 遍历链表,按照顺序存储结点的数据
int *data_list = (int*)malloc(N * sizeof(int));
int count = 0;
char current[6];
strcpy(current, head_address);
while(strcmp(current, "-1") != 0){
// 在数组中查找当前地址的结点
int found = 0;
for(int i=0; i<N; i++){
if(strcmp(nodes[i].address, current) == 0){
data_list[count++] = nodes[i].data;
strcpy(current, nodes[i].next);
found = 1;
break;
}
}
if(!found){
break; // 如果地址不存在,结束遍历
}
}
// 计算中间结点的位置并输出
if(count == 0){
// 如果链表为空,什么也不输出
}
else{
int mid = count / 2;
printf("%d\n", data_list[mid]);
}
// 释放动态分配的内存
free(data_list);
return 0;
}
九、C++算法源码
// C++ 版本
#include <bits/stdc++.h>
using namespace std;
struct Node {
string address; // 结点地址
int data; // 结点数据
string next; // 下一个结点地址
};
int main(){
string head_address;
int N;
// 读取首结点地址和结点总数
cin >> head_address >> N;
// 创建一个unordered_map来存储地址到结点数据和下一个地址的映射
unordered_map<string, pair<int, string>> node_map;
for(int i=0; i<N; i++){
string address, next;
int data;
cin >> address >> data >> next;
node_map[address] = make_pair(data, next);
}
// 遍历链表,按照顺序存储结点的数据
vector<int> data_list;
string current = head_address;
while(current != "-1"){
if(node_map.find(current) == node_map.end()) break; // 如果地址不存在,结束遍历
data_list.push_back(node_map[current].first);
current = node_map[current].second;
}
// 计算中间结点的位置并输出
if(data_list.empty()){
// 如果链表为空,什么也不输出
}
else{
int mid = data_list.size() / 2;
cout << data_list[mid] << endl;
}
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。