java解法

问题背景:

给定一个链表,每个节点包含两个信息:
节点的值。
下一个节点的标识符(或标记为 -1,表示链表结束)。
输入数据包含链表的起始节点、节点数目及每个节点的详细信息。
需要找出链表中的环的入口节点,如果存在环。
思路:

使用哈希表存储节点信息:我们使用一个 Map 来保存每个节点的值和指向下一个节点的标识符。
快慢指针法:
使用两个指针 slow 和 fast,slow 每次移动一步,fast 每次移动两步。
如果链表存在环,两个指针最终会相遇。
在快慢指针相遇后,重新设置一个指针从起始节点开始,每次一步一步前进,另一个指针不动,最终会在环的入口节点相遇。
输出环的入口节点的值。

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {

    // 定义链表节点类
    public static class Node {
        int val;       // 节点的值
        String next;   // 指向下一个节点的标识符
        // 构造函数初始化节点
        public Node(int val, String next) {
            this.val = val;
            this.next = next;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Map<String, Node> map = new HashMap<>(); // 用哈希表存储每个节点的信息
        // 读取输入的起始节点和节点数目
        String[] input = sc.nextLine().split(" ");
        String start = input[0]; // 起始节点
        int n = Integer.parseInt(input[1]); // 节点数目

        // 读取每个节点的信息,填充到哈希表中
        for (int i = 0; i < n; i++) {
            String[] nodeInfo = sc.nextLine().split(" ");
            map.put(nodeInfo[0], new Node(Integer.parseInt(nodeInfo[1]), nodeInfo[2]));
        }

        // 初始化快慢指针,初始位置均为起始节点
        String slow = start, fast = start;
        
        // 快慢指针法:快指针每次走两步,慢指针每次走一步
        // 如果有环,快指针和慢指针一定会相遇
        while (!fast.equals("-1") && !map.get(fast).next.equals("-1")) {
            slow = map.get(slow).next; // 慢指针走一步
            fast = map.get(map.get(fast).next).next; // 快指针走两步
        }

        // 输出慢指针所在节点的值,作为环的入口节点的值
        System.out.println(map.get(slow).val);
    }
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C++解法

具体思路如下:

链表的表示:

每个节点包含 data(节点的值)和 next(指向下一个节点的地址或 -1,表示链表结束)。
使用哈希表(unordered_map)存储链表中每个节点的地址和节点数据。
环检测和寻找环的入口节点:

使用 快慢指针(slow 和 fast),其中 slow 每次走一步,fast 每次走两步。
如果链表中存在环,slow 和 fast 指针最终会相遇。
在相遇之后,重新设置一个指针从链表的起始节点开始,每次一步一步前进,另一个指针不动,最终会在环的入口处相遇。
输出环的入口节点的值。
主要步骤:

读取输入,构建链表。
使用快慢指针检测环并找到入口节点。

#include 
#include 
#include 
using namespace std;

// 链表节点结构体
struct Node {
    int data;      // 节点的值
    string next;   // 下一节点的地址(字符串)

    // 默认构造函数
    Node() : data(0), next("") {}

    // 带参数的构造函数
    Node(int data, const string& next) : data(data), next(next) {}
};

// 查找环的入口节点
void find_middle_node() {
    unordered_map nodes; // 哈希表,用于存储每个节点
    string first;  // 链表的起始节点地址
    int n;         // 节点的数量

    // 读取起始节点地址和节点数量
    cin >> first >> n;
    cin.ignore();  // 忽略行尾的换行符

    // 读取每个节点的信息并存入哈希表
    for (int i = 0; i < n; ++i) {
        string addr, next_addr;  // 当前节点地址和下一节点的地址
        int data;                // 当前节点的值
        cin >> addr >> data >> next_addr;
        nodes[addr] = Node(data, next_addr);  // 将节点信息存入哈希表
    }

    // 快慢指针初始化,分别从起始节点开始
    string slow = first, fast = first;

    // 快慢指针法:快指针每次走两步,慢指针每次走一步
    // 如果有环,快指针和慢指针最终会相遇
    while (fast != "-1" && nodes[fast].next != "-1") {
        slow = nodes[slow].next;  // 慢指针走一步
        fast = nodes[nodes[fast].next].next;  // 快指针走两步
    }

    // 输出慢指针所在的节点数据,作为环的入口节点
    cout << nodes[slow].data << endl;
}

// 主函数,执行链表环入口查找
int main() {
    find_middle_node();  // 调用函数查找环的入口节点
    return 0;
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

节点的地址。
节点的值。
指向下一个节点的地址,若指向 -1 表示链表结束。
我们可以通过以下步骤来解决问题:

构建链表:使用一个哈希映射(Map)存储每个节点的地址和节点对象。每个节点对象包含节点的值和指向下一个节点的地址。
遍历链表:从给定的起始节点开始,按照链表的连接关系遍历链表,将节点按顺序存入数组
找中间节点:找到链表的中间节点。可以通过计算链表长度的一半索引来获得中间节点,并返回它的值。

// 定义链表节点类
class Node {
    constructor(data, next) {
        this.data = data;  // 节点的值
        this.next = next;  // 指向下一个节点的地址
    }
}

// 查找链表的中间节点
function findMiddleNode(start, nodes) {
    let list = [];  // 用于存储链表节点的数组
    let current = start;  // 从起始节点开始遍历

    // 遍历链表,直到找到终点 '-1'
    while (current !== '-1') {
        const node = nodes.get(current);  // 获取当前节点
        list.push(node);  // 将节点添加到数组中
        current = node.next;  // 更新当前节点为下一个节点
    }

    // 返回中间节点的值
    return list[Math.floor(list.length / 2)].data;
}

// 示例用法:读取输入并执行操作
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 读取第一行,获取链表的起始节点和节点数量
rl.question('', (firstLine) => {
    const [start, count] = firstLine.split(" ");  // 获取起始节点地址和节点数量
    const nodes = new Map();  // 创建一个哈希映射存储所有节点
    let linesRead = 0;  // 记录已经读取的节点数量

    // 监听每一行输入
    rl.on('line', (line) => {
        const [address, data, next] = line.split(" ");  // 解析每个节点的地址、值和下一个地址
        nodes.set(address, new Node(parseInt(data), next));  // 将节点存入哈希映射
        linesRead++;  // 更新已读取的节点数量

        // 当读取的节点数等于总节点数时,输出中间节点的值
        if (linesRead === parseInt(count)) {
            console.log(findMiddleNode(start, nodes));  // 找到中间节点并输出
            rl.close();  // 关闭输入流
        }
    });
});

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/144513635"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!