Skip to content

feat: add solution for problem no.1114 and no.1115 #298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.toml
.idea
.vscode
50 changes: 29 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,33 @@

<a href="https://books.halfrost.com/leetcode/"><img src="./website/static/logo.png" alt="logo" height="550" align="right" /></a>

* [Array](#array)
* [String](#string)
* [✅ Two Pointers](#two-pointers)
* [✅ Linked List](#linked-list)
* [✅ Stack](#stack)
* [Tree](#tree)
* [Dynamic programming](#dynamic-programming)
* [✅ Backtracking](#backtracking)
* [Depth First Search](#depth-first-search)
* [Breadth First Search](#breadth-first-search)
* [Binary Search](#binary-search)
* [Math](#math)
* [Hash Table](#hash-table)
* [✅ Sort](#sort)
* [✅ Bit Manipulation](#bit-manipulation)
* [✅ Union Find](#union-find)
* [✅ Sliding Window](#sliding-window)
* [✅ Segment Tree](#segment-tree)
* [✅ Binary Indexed Tree](#binary-indexed-tree)
- [LeetCode in Go](#leetcode-in-go)
- [Data Structures](#data-structures)
- [Algorithm](#algorithm)
- [LeetCode Problems](#leetcode-problems)
- [一. 个人数据](#一-个人数据)
- [二. 目录](#二-目录)
- [三.分类](#三分类)
- [Array](#array)
- [String](#string)
- [Two Pointers](#two-pointers)
- [Linked List](#linked-list)
- [Stack](#stack)
- [Tree](#tree)
- [Dynamic Programming](#dynamic-programming)
- [Backtracking](#backtracking)
- [Depth First Search](#depth-first-search)
- [Breadth First Search](#breadth-first-search)
- [Binary Search](#binary-search)
- [Math](#math)
- [Hash Table](#hash-table)
- [Sort](#sort)
- [Bit Manipulation](#bit-manipulation)
- [Union Find](#union-find)
- [Sliding Window](#sliding-window)
- [Segment Tree](#segment-tree)
- [Binary Indexed Tree](#binary-indexed-tree)
- [♥️ Thanks](#️-thanks)

<br>
<br>
Expand Down Expand Up @@ -1252,8 +1260,8 @@
|1111|Maximum Nesting Depth of Two Valid Parentheses Strings|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/1111.Maximum-Nesting-Depth-of-Two-Valid-Parentheses-Strings)|73.3%|Medium||
|1112|Highest Grade For Each Student||73.8%|Medium||
|1113|Reported Posts||66.1%|Easy||
|1114|Print in Order||68.1%|Easy||
|1115|Print FooBar Alternately||61.7%|Medium||
|1114|Print in Order|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/1114.Print-in-Order)|68.1%|Easy||
|1115|Print FooBar Alternately|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/1115.Print-FooBar-Alternately)|61.7%|Medium||
|1116|Print Zero Even Odd||60.1%|Medium||
|1117|Building H2O||55.7%|Medium||
|1118|Number of Days in a Month||56.7%|Easy||
Expand Down
36 changes: 36 additions & 0 deletions leetcode/1114.Print-in-Order/1114. Print in Order.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package leetcode

import "fmt"

type Foo struct {
chans []chan bool
}

func NewFoo() *Foo {
pt := Foo{}
pt.chans = make([]chan bool, 0)
for i := 0; i < 2; i++ {
pt.chans = append(pt.chans, make(chan bool, 1))
}
return &pt
}

func (this *Foo) first() {
fmt.Print("first")
this.chans[0] <- true
}

func (this *Foo) second() {
select {
case <-this.chans[0]:
fmt.Print("second")
this.chans[1] <- true
}
}

func (this *Foo) third() {
select {
case <-this.chans[1]:
fmt.Print("third")
}
}
83 changes: 83 additions & 0 deletions leetcode/1114.Print-in-Order/1114. Print in Order_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package leetcode

import (
"fmt"
"testing"
"time"
)

type question1114 struct {
para1114
ans1114
}

// para 是参数
// one 代表第一个参数
type para1114 struct {
one []int
}

// ans 是答案
// one 代表第一个答案
type ans1114 struct {
one string
}

func Test_Problem1114(t *testing.T) {

qs := []question1114{

{
para1114{[]int{1, 2, 3}},
ans1114{"firstsecondthird"},
},

{
para1114{[]int{1, 3, 2}},
ans1114{"firstsecondthird"},
},

{
para1114{[]int{2, 1, 3}},
ans1114{"firstsecondthird"},
},

{
para1114{[]int{2, 3, 1}},
ans1114{"firstsecondthird"},
},

{
para1114{[]int{3, 1, 2}},
ans1114{"firstsecondthird"},
},

{
para1114{[]int{3, 2, 1}},
ans1114{"firstsecondthird"},
},
}

fmt.Printf("------------------------Leetcode Problem 1114------------------------\n")

for _, q := range qs {
_, p := q.ans1114, q.para1114
fooIns := NewFoo()
fmt.Printf("【input】:%v 【output】:", p)
for _, v := range q.para1114.one {
switch v {
case 1:
go fooIns.first()
case 2:
go fooIns.second()
case 3:
go fooIns.third()
default:
panic("problem does not support input other than '1, 2, 3'")
}
}
time.Sleep(time.Second)
fmt.Printf("\n")
}
fmt.Printf("\n\n\n")
}
44 changes: 44 additions & 0 deletions leetcode/1114.Print-in-Order/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# [1114. Print in Order](https://leetcode.com/problems/print-in-order/)

## 题目

Suppose we have a class:

```java
public class Foo {
public void first() { print("first"); }
public void second() { print("second"); }
public void third() { print("third"); }
}
```

The same instance of Foo will be passed to three different threads. Thread A will call `first()`, thread B will call `second()`, and thread C will call `third()`. Design a mechanism and modify the program to ensure that `second()` is executed after `first()`, and `third()` is executed after `second()`.

**Note:**

We do not know how the threads will be scheduled in the operating system, even though the numbers in the input seem to imply the ordering. The input format you see is mainly to ensure our tests' comprehensiveness.

**Example 1:**

Input: nums = [1,2,3]
Output: "firstsecondthird"
Explanation: There are three threads being fired asynchronously. The input [1,2,3] means thread A calls first(), thread B calls second(), and thread C calls third(). "firstsecondthird" is the correct output.

**Example 2:**

Input: nums = [1,3,2]
Output: "firstsecondthird"
Explanation: The input [1,3,2] means thread A calls first(), thread B calls third(), and thread C calls second(). "firstsecondthird" is the correct output.

**Constraints:**

- `nums` is a permutation of `[1, 2, 3]`.


## 题目大意

实现一个可以按需打印“first”、“second”和“third”的类,无论并发调用的顺序如何,均可保持按从小到大打印的位次。

## 解题思路

- Golang中可以使用Channel实现多个协程执行的顺序依赖。通过有缓冲区的Channel实现写入不阻塞,读取阻塞的功能;通过select使预期靠后执行的协程阻塞等待其它协程执行完毕。
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package leetcode

import "fmt"

type FooBar struct {
chans []chan bool
limit int
printed []int
}

func NewFooBar(n int) *FooBar {
pt := FooBar{}
pt.limit = n
pt.printed = make([]int, 2)
pt.chans = make([]chan bool, 2)
for idx := range pt.chans {
pt.chans[idx] = make(chan bool, 1)
}
pt.chans[0] <- true
return &pt
}

func (this *FooBar) foo() {
for this.printed[0] < this.limit {
select {
case <-this.chans[0]:
if this.printed[0] >= this.limit {
return
}
fmt.Printf("foo")
this.printed[0]++
this.chans[1] <- true
}
}
}

func (this *FooBar) bar() {
for this.printed[1] < this.limit {
select {
case <-this.chans[1]:
if this.printed[1] >= this.limit {
return
}
fmt.Printf("bar")
this.printed[1]++
this.chans[0] <- true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package leetcode

import (
"fmt"
"math/rand"
"testing"
"time"
)

type question1115 struct {
para1115
ans1115
}

// para 是参数
// one 代表第一个参数
type para1115 struct {
one int
}

// ans 是答案
// one 代表第一个答案
type ans1115 struct {
one string
}

func Test_Problem1115(t *testing.T) {

qs := []question1115{

{
para1115{1},
ans1115{"foobar"},
},

{
para1115{2},
ans1115{"foobarfoobar"},
},

{
para1115{3},
ans1115{"foobarfoobarfoobar"},
},

{
para1115{4},
ans1115{"foobarfoobarfoobarfoobar"},
},

{
para1115{5},
ans1115{"foobarfoobarfoobarfoobarfoobar"},
},

{
para1115{6},
ans1115{"foobarfoobarfoobarfoobarfoobarfoobar"},
},
}

fmt.Printf("------------------------Leetcode Problem 1115------------------------\n")

for _, q := range qs {
fooBarIns := NewFooBar(q.para1115.one)
fmt.Printf("【input】:%v 【output】:", q.para1115.one)
coin := rand.Intn(1)
if coin == 0 {
go fooBarIns.foo()
go fooBarIns.bar()
} else {
go fooBarIns.bar()
go fooBarIns.foo()
}
time.Sleep(time.Second)
fmt.Printf("\n")
}
fmt.Printf("\n\n\n")
}
Loading