LeetCode H2O 生成
第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 生成的更多相关文章
- Leetcode 22.生成括号对数
生成括号对数 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n =3,生成结果为: [ "((()))", "( ...
- LeetCode 题解目录
前言 本目录将不断更新记录leetcode的刷题日记. 二叉树 序号 标题 难度 标签 1 108 将有序数组转换为二叉搜索树 简单 树.深度优先搜索 2 538 把二叉搜索树转换为累加树 简单 树 ...
- leetcode难题
4 寻找两个有序数组的中位数 35.9% 困难 10 正则表达式匹配 24.6% 困难 23 合并K个排序链表 47.4% 困难 25 K ...
- Oracle 11g数据库详解(2)
FAILED_LOGIN_ATTEMPTS 用于指定连续登陆失败的最大次数 达到最大次数后,用户会被锁定,登陆时提示ORA-28000 UNLIMITED为不限制 精确无误差 是 实时 PASSWOR ...
- [LeetCode] Generate Parentheses 生成括号
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- [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 ...
- leetcode 22括号生成
非常好的一道题.一开始的思想是这样的,先把n对括号按照某一顺序生成一个string,然后用全排列算法生成所有可能,然后利用stack写一段判断括号是否匹配的字符串,匹配的假如结果中.不过会超时.因为全 ...
- [LeetCode] “全排列”问题系列(一) - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题
一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer上的一道例题入手,小谈一下这种类型题目的解法. 二.上手 最典型的permutation题目是这样的 ...
- “全排列”问题系列(一)[LeetCode] - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题
转:http://www.cnblogs.com/felixfang/p/3705754.html 一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer ...
随机推荐
- 关于layer的基本所有的事件全部失效问题
只要在页面中,要是存在id="undefined", layer的基本所有的事件全部失效. <input type="radio" id="un ...
- 我的第一个 python 爬虫脚本
#!/usr/bin/env python# coding=utf-8import urllib2from bs4 import BeautifulSoup #res = urllib.urlopen ...
- Linux 使用 docker 下搭建xunsearch 搜索引擎服务
Linux 使用 docker 下搭建 xunsearch 搜索引擎服务 安装 docker 环境(菜鸟教程有说明) 安装docker说明 下载并运行 xunsearch 的服务端:docker安装x ...
- SQL语句中将形式(12/10/19 4:13:21 PM)转化为(2019-12-10)
convert(char(10),convert(datetime, H.TOEX_FIN_REJECT_TIMR)+1,20),
- [TimLinux] Linux shell获取进程pid
调用脚本时,获取进程PID: (/this/is/a/script/file.sh > /out/to/log.txt & echo $!) & 脚本内部,获取进程PID: ec ...
- [TimLinux] selinux sesearch命令详解
1. 描述 sesearch用于搜索SELinux安全策略规则集,命令来自包:yum install setools-console. 2. 命令 命令使用方法: sesearch [OPTIONS] ...
- 洛谷 题解 P3385 【【模板】负环】
一.声明 在下面的描述中,未说明的情况下,\(N\) 是顶点数,\(M\)是边数. 二.判负环算法盘点 想到判负环,我们会想到很多的判负环算法.例如: 1. Bellman-Ford 判负环 这个算法 ...
- 【JS】376- Axios 使用指南
点击上方"前端自习课"关注,学习起来~ 来源 | https://www.jianshu.com/p/df464b26ae58 一.axios 基于promise用于浏览器和 ...
- 大数据学习笔记——Java篇之网络编程基础
Java网络编程学习笔记 1. 网络编程基础知识 1.1 网络分层图 网络分层分为两种模型:OSI模型以及TCP/IP网络模型,前者模型分为7层,是一个理论的,参考的模型:后者为实际应用的模型,具体对 ...
- leetcode-164、最大间距
export default (arr) => { // 如果数组长度小于2返回0 if (arr.length < 2) { return 0 } // 排序 arr.sort() // ...