草庐IT

华为OD机试 - 单向链表中间节点(Java & JS & Python)

伏城之外 2023-05-28 原文

题目描述

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

输入描述

第一行 链表头节点地址 后续输入的节点数n

后续输入每行表示一个节点,格式 节点地址 节点值 下一个节点地址(-1表示空指针)

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

输出描述

单向链表中间的节点值

用例

输入00010 4
00000 3 -1
00010 5 12309
11451 6 00000
12309 7 11451
输出6
说明
输入10000 3
76892 7 12309
12309 5 -1
10000 1 76892
输出7
说明

题目解析

用例1示意图如下

JS本题可以利用数组模拟链表 

基于链表数据结构解题

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
let head;
let n;
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 1) {
    [head, n] = lines[0].split(" ");
  }

  if (n && lines.length === n - 0 + 1) {
    lines.shift();

    const nodes = {};

    lines.forEach((line) => {
      const [addr, val, nextAddr] = line.split(" ");
      nodes[addr] = [val, nextAddr];
    });

    console.log(getResult(head, nodes));

    lines.length = 0;
  }
});

function getResult(head, nodes) {
  const linkedlist = [];

  let node = nodes[head];
  while (node) {
    const [val, next] = node;

    linkedlist.push(val);
    node = nodes[next];
  }

  const len = linkedlist.length;

  const mid = len % 2 === 0 ? len / 2 : Math.floor(len / 2);

  return linkedlist[mid];
}

Java算法源码

需要注意的是Java中LinkedList类的get(index)方法的时间复杂度不是O(1),而是O(n),这题建议使用ArrayList代替

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    String head = sc.next();
    int n = sc.nextInt();

    HashMap<String, String[]> nodes = new HashMap<>();
    for (int i = 0; i < n; i++) {
      String addr = sc.next();
      String val = sc.next();
      String nextAddr = sc.next();
      nodes.put(addr, new String[] {val, nextAddr});
    }

    System.out.println(getResult(head, nodes));
  }

  public static String getResult(String head, HashMap<String, String[]> nodes) {
    //    LinkedList<String> link = new LinkedList<>();
    ArrayList<String> link = new ArrayList<>();

    String[] node = nodes.get(head);
    while (node != null) {
      String val = node[0];
      String next = node[1];

      link.add(val);
      node = nodes.get(next);
    }

    int len = link.size();
    int mid = len / 2;
    return link.get(mid);
  }
}

Python算法源码

# 输入获取
head, n = input().split()

nodes = {}
for i in range(int(n)):
    addr, val, nextAddr = input().split()
    nodes[addr] = [val, nextAddr]


# 算法入口
def getResult(head, nodes):
    linkedlist = []
    node = nodes.get(head)

    while node is not None:
        val, next = node
        linkedlist.append(val)
        node = nodes.get(next)

    length = len(linkedlist)
    mid = int(length / 2)

    return linkedlist[mid]


# 算法调用
print(getResult(head, nodes))

快慢指针解题

链表数据结构本质上来说没有索引概念,因为其在内存上不是一段连续的内存,因此索引对于链表结构而言没有意义。

但是从使用上来说,我又经常需要去获取链表结构的第几个元素,因此大部分语言都为链表结构提高了“假索引”,比如Java的LinkedList类,虽然提高了get(index)方法,但是其底层是通过遍历链表(通过next属性找到下一个节点)来找到对应“假索引”的元素的,即LinkedList每次都需要O(n)的时间复杂度才能找到index位置上的元素。

另外,链表还有一个常考问题,那就是链表长度未知的情况下,我们如何找到链表的中间节点?

此时,就要用到快慢指针。

所谓快慢指针,即通过两个指针遍历链表,慢指针每次步进1个节点,快指针每次步进2个节点,这样快指针必然先到达链表尾部,而当快指针到达链表尾部时,慢指针其实刚好就是在链表中间节点的位置(奇数个节点取中间,偶数个取偏右边的那个值)。

本题虽然给出了节点数,但是这些节点不一定属于同一个链表结构,因此本题的链表长度也是未知的,而本题要求的链表中间节点要求刚好和快慢指针找的中间节点吻合,因此本题最佳策略是使用快慢指针。

Java算法源码

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

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    String head = sc.next();
    int n = sc.nextInt();

    HashMap<String, String[]> nodes = new HashMap<>();
    for (int i = 0; i < n; i++) {
      String addr = sc.next();
      String val = sc.next();
      String nextAddr = sc.next();
      nodes.put(addr, new String[] {val, nextAddr});
    }

    System.out.println(getResult(head, nodes));
  }

  public static String getResult(String head, HashMap<String, String[]> nodes) {
    String[] slow = nodes.get(head);
    String[] fast = nodes.get(slow[1]);

    while (fast != null) {
      slow = nodes.get(slow[1]);

      fast = nodes.get(fast[1]);
      if (fast != null) {
        fast = nodes.get(fast[1]);
      } else {
        break;
      }
    }

    return slow[0];
  }
}

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
let head;
let n;
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 1) {
    [head, n] = lines[0].split(" ");
  }

  if (n && lines.length === n - 0 + 1) {
    lines.shift();

    const nodes = {};

    lines.forEach((line) => {
      const [addr, val, nextAddr] = line.split(" ");
      nodes[addr] = [val, nextAddr];
    });

    console.log(getResult(head, nodes));

    lines.length = 0;
  }
});

function getResult(head, nodes) {
  let slow = nodes[head];
  let fast = nodes[slow[1]];

  while (fast) {
    slow = nodes[slow[1]];

    fast = nodes[fast[1]];
    if (fast) {
      fast = nodes[fast[1]];
    } else {
      break;
    }
  }

  return slow[0];
}

Python算法源码

# 输入获取
head, n = input().split()

nodes = {}
for i in range(int(n)):
    addr, val, nextAddr = input().split()
    nodes[addr] = [val, nextAddr]


# 算法入口
def getResult(head, nodes):
    slow = nodes.get(head)
    fast = nodes.get(slow[1])

    while fast is not None:
        slow = nodes.get(slow[1])

        fast = nodes.get(fast[1])
        if fast is None:
            break
        else:
            fast = nodes.get(fast[1])

    return slow[0]


# 算法调用
print(getResult(head, nodes))

有关华为OD机试 - 单向链表中间节点(Java & JS & Python)的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  4. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  5. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  6. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  9. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐