华为OD机试 - 单向链表中间节点(Python/JS/C/C++ 2024 E卷 200分)

在这里插入图片描述

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

专栏导读

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

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

一、题目描述

求单向链表中间的节点值,如果奇数个节点取中间,偶数个取偏右边的那个值。

二、输入描述

第一行 链表头节点地址 后续输入的节点数 n
后续输入每行表示一个节点,格式:节点地址 节点值 节点地址 下一个节点地址(-1 表示空指针 Q)

输入保证链表不会出现环,并且可能存在一些节点不属于链表。

三、输出描述

单向链表中间的节点值

四、测试用例

测试用例1:

1、输入

00010 4
00000 3 -1
00010 5 12309
11451 6 00000
12309 7 11451

2、输出

6

3、说明

链表顺序为:00010 (5) -> 12309 (7) -> 11451 (6) -> 00000 (3)
总节点数为 4,偶数,取第 3 个节点的值为 6。

测试用例2:

1、输入

10000 3
76892 7 12309
12309 5 -1
10000 1 76892

2、输出

7

3、说明

链表顺序为:10000 (1) -> 76892 (7) -> 12309 (5)
总节点数为 3,奇数,取第 2 个节点的值为 7。

五、解题思路

  1. 输入读取:
    • 使用 Scanner 从标准输入读取链表的头节点地址和节点总数 n。
    • 读取接下来的 n 行,每行包含一个节点的地址、值和下一个节点的地址。
    • 使用 HashMap<String, Node> 将节点地址映射到对应的 Node 对象,便于快速查找节点。
  2. 链表遍历:
    • 从头节点地址开始,依次通过 next 地址遍历链表。
    • 将遍历到的每个节点的值存储在 List nodeValues 中。
    • 如果遇到地址为 -1,表示链表结束;或者当前地址在 HashMap 中不存在,表示链表异常结束。
  3. 中间节点查找:
    • 根据链表长度 size 计算中间节点的索引 middleIndex。
    • 对于奇数个节点,middleIndex = size / 2,例如 5 个节点,索引为 2。
    • 对于偶数个节点,middleIndex = size / 2,例如 4 个节点,索引为 2(偏右)。
    • 输出中间节点的值。
  4. 辅助类:
    • Node 类用于表示链表中的每个节点,包含地址、值和下一个节点的地址。

六、Python算法源码

# 导入所需的模块
import sys

def main():
    # 读取输入
    input = sys.stdin.read().split()
    idx = 0
    
    # 读取链表头节点地址和节点总数 n
    head_address = input[idx]
    idx += 1
    n = int(input[idx])
    idx += 1
    
    # 使用字典存储所有节点的信息,键为节点地址,值为(值, 下一个节点地址)
    node_map = {}
    for _ in range(n):
        address = input[idx]
        idx += 1
        value = int(input[idx])
        idx += 1
        next_address = input[idx]
        idx += 1
        node_map[address] = (value, next_address)
    
    # 遍历链表,按顺序收集节点的值
    node_values = []
    current_address = head_address
    while current_address != "-1":
        if current_address not in node_map:
            # 如果当前地址不存在于 node_map 中,链表结束
            break
        current_node = node_map[current_address]
        node_values.append(current_node[0])
        current_address = current_node[1]
    
    # 判断链表是否为空
    if not node_values:
        print("链表为空。")
    else:
        # 计算中间节点的索引
        size = len(node_values)
        middle_index = size // 2  # 对于偶数,取偏右边的节点
        print(node_values[middle_index])

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// 定义节点类,表示链表中的每个节点
class Node {
    constructor(address, value, next) {
        this.address = address; // 节点地址
        this.value = value;     // 节点值
        this.next = next;       // 下一个节点的地址
    }
}

// 主函数
function main() {
    const fs = require('fs');
    const input = fs.readFileSync('/dev/stdin').toString().trim().split(/\s+/);
    let idx = 0;
    
    // 读取链表头节点地址和节点总数 n
    const headAddress = input[idx++];
    const n = parseInt(input[idx++]);
    
    // 使用对象存储所有节点的信息,键为节点地址,值为 Node 对象
    const nodeMap = {};
    for (let i = 0; i < n; i++) {
        const address = input[idx++];
        const value = parseInt(input[idx++]);
        const next = input[idx++];
        nodeMap[address] = new Node(address, value, next);
    }
    
    // 遍历链表,按顺序收集节点的值
    const nodeValues = [];
    let currentAddress = headAddress;
    while (currentAddress !== "-1") {
        if (!(currentAddress in nodeMap)) {
            // 如果当前地址不存在于 nodeMap 中,链表结束
            break;
        }
        const currentNode = nodeMap[currentAddress];
        nodeValues.push(currentNode.value);
        currentAddress = currentNode.next;
    }
    
    // 判断链表是否为空
    if (nodeValues.length === 0) {
        console.log("链表为空。");
    } else {
        // 计算中间节点的索引
        const size = nodeValues.length;
        const middleIndex = Math.floor(size / 2); // 对于偶数,取偏右边的节点
        console.log(nodeValues[middleIndex]);
    }
}

// 执行主函数
main();

八、C算法源码

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

// 定义最大地址长度
#define MAX_ADDR_LEN 20

// 定义节点结构体
typedef struct Node {
    char address[MAX_ADDR_LEN]; // 节点地址
    int value;                   // 节点值
    char next[MAX_ADDR_LEN];    // 下一个节点的地址
} Node;

// 主函数
int main() {
    char headAddress[MAX_ADDR_LEN];
    int n;
    
    // 读取链表头节点地址和节点总数 n
    scanf("%s %d", headAddress, &n);
    
    // 使用数组存储所有节点的信息
    Node *nodeMap = (Node *)malloc(n * sizeof(Node));
    for (int i = 0; i < n; i++) {
        scanf("%s %d %s", nodeMap[i].address, &nodeMap[i].value, nodeMap[i].next);
    }
    
    // 遍历链表,按顺序收集节点的值
    int *nodeValues = (int *)malloc(n * sizeof(int));
    int count = 0;
    char currentAddress[MAX_ADDR_LEN];
    strcpy(currentAddress, headAddress);
    
    while (strcmp(currentAddress, "-1") != 0) {
        int found = 0;
        for (int i = 0; i < n; i++) {
            if (strcmp(nodeMap[i].address, currentAddress) == 0) {
                nodeValues[count++] = nodeMap[i].value;
                strcpy(currentAddress, nodeMap[i].next);
                found = 1;
                break;
            }
        }
        if (!found) {
            // 如果当前地址不存在于 nodeMap 中,链表结束
            break;
        }
    }
    
    // 判断链表是否为空
    if (count == 0) {
        printf("链表为空。\n");
    } else {
        // 计算中间节点的索引
        int middleIndex = count / 2; // 对于偶数,取偏右边的节点
        printf("%d\n", nodeValues[middleIndex]);
    }
    
    // 释放动态分配的内存
    free(nodeMap);
    free(nodeValues);
    
    return 0;
}

九、C++算法源码

#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>

using namespace std;

// 定义节点结构体
struct Node {
    string address; // 节点地址
    int value;      // 节点值
    string next;    // 下一个节点的地址
};

int main() {
    string headAddress;
    int n;
    
    // 读取链表头节点地址和节点总数 n
    cin >> headAddress >> n;
    
    // 使用无序映射存储所有节点的信息,键为节点地址,值为 Node 结构体
    unordered_map<string, Node> nodeMap;
    for (int i = 0; i < n; ++i) {
        string address, next;
        int value;
        cin >> address >> value >> next;
        nodeMap[address] = Node{address, value, next};
    }
    
    // 遍历链表,按顺序收集节点的值
    vector<int> nodeValues;
    string currentAddress = headAddress;
    while (currentAddress != "-1") {
        if (nodeMap.find(currentAddress) == nodeMap.end()) {
            // 如果当前地址不存在于 nodeMap 中,链表结束
            break;
        }
        Node currentNode = nodeMap[currentAddress];
        nodeValues.push_back(currentNode.value);
        currentAddress = currentNode.next;
    }
    
    // 判断链表是否为空
    if (nodeValues.empty()) {
        cout << "链表为空。" << endl;
    } else {
        // 计算中间节点的索引
        int size = nodeValues.size();
        int middleIndex = size / 2; // 对于偶数,取偏右边的节点
        cout << nodeValues[middleIndex] << endl;
    }
    
    return 0;
}


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

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

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值