第1117题

现在有两种线程,氢 oxygen 和氧 hydrogen,你的目标是组织这两种线程来产生水分子。

存在一个屏障(barrier)使得每个线程必须等候直到一个完整水分子能够被产生出来。

氢和氧线程会被分别给予 releaseHydrogen 和 releaseOxygen 方法来允许它们突破屏障。

这些线程应该三三成组突破屏障并能立即组合产生一个水分子。

你必须保证产生一个水分子所需线程的结合必须发生在下一个水分子产生之前。

换句话说:

如果一个氧线程到达屏障时没有氢线程到达,它必须等候直到两个氢线程到达。
如果一个氢线程到达屏障时没有其它线程到达,它必须等候直到一个氧线程和另一个氢线程到达。
书写满足这些限制条件的氢、氧线程同步代码。   示例 1: 输入: "HOH"
输出: "HHO"
解释: "HOH" 和 "OHH" 依然都是有效解。
示例 2: 输入: "OOHHHH"
输出: "HHOHHO"
解释: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。
  限制条件: 输入字符串的总长将会是 3n, 1 ≤ n ≤ 50;
输入字符串中的 “H” 总数将会是 2n;
输入字符串中的 “O” 总数将会是 n。 来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/building-h2o

解题思路

  • 1.设定一个h信息号
  • 2.每生成一个h,当h等于2的时候则进入等待o。否则生成氢气并且h自加1。
  • 3.每生成一个o,当h小于2的时候则进入等侍h。否则生成o并且h清0,重新开始生成一个水份子
  • 4.注意Runnable和Thread的区别,实现了Runnable接口,无法启动线程,必须依托其他类或线程

代码实现

public class Sub1117 {
public static void main(String[] args) throws InterruptedException {
//测试用例字符串
String test = "HOHOHHOOHOHHHHHOHHHOH"; //生成结果字符串
StringBuffer result = new StringBuffer(); //注意:创建的Runnable任务,无法启动线程,必须依托其他类或线程启动
//创建生成氧气任务
Runnable releaseHydrogen = () -> result.append("H"); //创建生成氧气任务
Runnable releaseOxygen = () -> result.append("O"); //保存线程数组
Thread threads[] = new Thread[test.length()]; H2O h2o = new H2O();
for (int i = 0; i < test.length(); ++i) {
Thread thread = null;
//根据获得的字符调用相应的氧气或氢气线程
if (test.charAt(i) == 'O') {
thread = new OGenerator(h2o, releaseOxygen);
} else if (test.charAt(i) == 'H') {
thread = new HGenerator(h2o, releaseHydrogen);
}
//开始线程
thread.start();
//保存到线程数组
threads[i] = thread;
} //等侍所有线程执行完
for (int i = 0; i < threads.length; i++) {
threads[i].join();
} //输出结果串
System.out.println(result.toString());
}
} //氢气生成线程
class HGenerator extends Thread {
H2O h2o;
Runnable releaseHydrogen; public HGenerator(H2O h2o, Runnable releaseHydrogen) {
this.h2o = h2o;
this.releaseHydrogen = releaseHydrogen;
} @Override
public void run() {
try {
h2o.hydrogen(releaseHydrogen);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} //氧气生成线程
class OGenerator extends Thread {
H2O h2o;
Runnable releaseOxygen; public OGenerator(H2O h2o, Runnable releaseOxygen) {
this.h2o = h2o;
this.releaseOxygen = releaseOxygen;
} @Override
public void run() {
try {
h2o.oxygen(releaseOxygen);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} class H2O {
public H2O() {
} int h = 0; public synchronized void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
while (h == 2) {
this.wait();
}
releaseHydrogen.run();
++h;
this.notify();
} public synchronized void oxygen(Runnable releaseOxygen) throws InterruptedException {
while (h < 2) {
this.wait();
}
releaseOxygen.run();
h = 0;
this.notify();
}
}

资料

LeetCode H2O 生成的更多相关文章

  1. Leetcode 22.生成括号对数

    生成括号对数 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n =3,生成结果为: [ "((()))", "( ...

  2. LeetCode 题解目录

    前言 本目录将不断更新记录leetcode的刷题日记. 二叉树 序号 标题 难度 标签 1 108 将有序数组转换为二叉搜索树 简单 树.深度优先搜索 2 538 把二叉搜索树转换为累加树 简单 树 ...

  3. leetcode难题

    4 寻找两个有序数组的中位数       35.9% 困难     10 正则表达式匹配       24.6% 困难     23 合并K个排序链表       47.4% 困难     25 K ...

  4. Oracle 11g数据库详解(2)

    FAILED_LOGIN_ATTEMPTS 用于指定连续登陆失败的最大次数 达到最大次数后,用户会被锁定,登陆时提示ORA-28000 UNLIMITED为不限制 精确无误差 是 实时 PASSWOR ...

  5. [LeetCode] Generate Parentheses 生成括号

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  6. [LeetCode] Generate Random Point in a Circle 生成圆中的随机点

    Given the radius and x-y positions of the center of a circle, write a function randPoint which gener ...

  7. leetcode 22括号生成

    非常好的一道题.一开始的思想是这样的,先把n对括号按照某一顺序生成一个string,然后用全排列算法生成所有可能,然后利用stack写一段判断括号是否匹配的字符串,匹配的假如结果中.不过会超时.因为全 ...

  8. [LeetCode] “全排列”问题系列(一) - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题

    一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer上的一道例题入手,小谈一下这种类型题目的解法. 二.上手 最典型的permutation题目是这样的 ...

  9. “全排列”问题系列(一)[LeetCode] - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题

    转:http://www.cnblogs.com/felixfang/p/3705754.html 一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer ...

随机推荐

  1. ElasticSearch的API使用

    前言:之前写过如何安装ElasticSearch(以下简称ES)以及简单的crud的使用实例的博客,不过ElasticSearch的版本变化太快,像之前的5.6版本使用的TransPortClient ...

  2. Vue + TypeScript 踩坑总结

    vue 和 TypeScript 结合的情况下,很多写法和我们平时的写法都不太一样,这里总结我项目开发过程中遇到的问题和问题的解决方案 有些问题可能还没解决,欢迎各位大佬给与提点. 另外,使用本文前可 ...

  3. 输入URL到页面渲染

    输入网址回车或者刷新页面到页面传染出来的整个流程 DNS 解析 HTTP三次握手 -> TCP/IP连接 浏览器发送请求 服务器返回请求的文件 (html) 浏览器渲染 1. DNS 解析 查找 ...

  4. luogu P4462 [CQOI2018]异或序列 |莫队

    题目描述 已知一个长度为n的整数数列a1,a2,...,an,给定查询参数l.r,问在al,al+1,...,ar​区间内,有多少子序列满足异或和等于k.也就是说,对于所有的x,y (I ≤ x ≤ ...

  5. iOS开发-CoreMotion框架

    转自: CoreMotion是一个专门处理Motion的框架,其中包含了两个部分 加速度计和陀螺仪,在iOS4之前加速度计是由 UIAccelerometer 类 来负责采集数据,现在一般都是用Cor ...

  6. git配置文件—— .gitattributes

    目录 .gitattributes 文档 1. gitattributes文件以行为单位设置一个路径下所有文件的属性,格式如下: 2. 在gitattributes文件的一行中,一个属性(以text属 ...

  7. HDU1848 Fibonacci again and again(SG 函数)

    任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的: F(1)=1; F(2)=2; F(n)=F(n-1)+F(n-2)(n>=3); 所以,1, ...

  8. 2017 CCPC秦皇岛 L题 One Dimensions Dave

    BaoBao is trapped in a one-dimensional maze consisting of  grids arranged in a row! The grids are nu ...

  9. 【CuteJavaScript】Angular6入门项目(2.构建项目页面和组件)

    本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...

  10. java—将数据库读取的list转tree

    一.引言 有时候我们从数据库中读取出了一个表的数据,比如存储的是中国的省市县的ID.名称与父节点ID,读出来的数据并不是前台想要的,这个时候我们要想法处理一下都出来的list,将它变为一个树. 比如直 ...