From dd3ff75da22422c75fbb4d263bb994c8a43e173d Mon Sep 17 00:00:00 2001 From: ylink-lfs Date: Wed, 18 Jun 2025 21:00:39 +0800 Subject: [PATCH] feat: add solution for problem no.1114 and no.1115 --- .gitignore | 1 + README.md | 50 ++++++----- .../1114. Print in Order.go | 36 ++++++++ .../1114. Print in Order_test.go | 83 +++++++++++++++++++ leetcode/1114.Print-in-Order/README.md | 44 ++++++++++ .../1115. Print FooBar Alternately.go | 49 +++++++++++ .../1115. Print FooBar Alternately_test.go | 79 ++++++++++++++++++ .../1115.Print-FooBar-Alternately/README.md | 51 ++++++++++++ 8 files changed, 372 insertions(+), 21 deletions(-) create mode 100644 leetcode/1114.Print-in-Order/1114. Print in Order.go create mode 100644 leetcode/1114.Print-in-Order/1114. Print in Order_test.go create mode 100755 leetcode/1114.Print-in-Order/README.md create mode 100644 leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately.go create mode 100644 leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately_test.go create mode 100755 leetcode/1115.Print-FooBar-Alternately/README.md diff --git a/.gitignore b/.gitignore index e1e2e99aa..bc73c5327 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.toml .idea +.vscode diff --git a/README.md b/README.md index ebb30e7d1..556ae8b6c 100755 --- a/README.md +++ b/README.md @@ -63,25 +63,33 @@ logo -* [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)

@@ -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|| diff --git a/leetcode/1114.Print-in-Order/1114. Print in Order.go b/leetcode/1114.Print-in-Order/1114. Print in Order.go new file mode 100644 index 000000000..3da8eb7df --- /dev/null +++ b/leetcode/1114.Print-in-Order/1114. Print in Order.go @@ -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") + } +} diff --git a/leetcode/1114.Print-in-Order/1114. Print in Order_test.go b/leetcode/1114.Print-in-Order/1114. Print in Order_test.go new file mode 100644 index 000000000..daf29dd2a --- /dev/null +++ b/leetcode/1114.Print-in-Order/1114. Print in Order_test.go @@ -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") +} diff --git a/leetcode/1114.Print-in-Order/README.md b/leetcode/1114.Print-in-Order/README.md new file mode 100755 index 000000000..51e3970f8 --- /dev/null +++ b/leetcode/1114.Print-in-Order/README.md @@ -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使预期靠后执行的协程阻塞等待其它协程执行完毕。 diff --git a/leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately.go b/leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately.go new file mode 100644 index 000000000..40d8d25b1 --- /dev/null +++ b/leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately.go @@ -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 + } + } +} diff --git a/leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately_test.go b/leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately_test.go new file mode 100644 index 000000000..74deda3ee --- /dev/null +++ b/leetcode/1115.Print-FooBar-Alternately/1115. Print FooBar Alternately_test.go @@ -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") +} diff --git a/leetcode/1115.Print-FooBar-Alternately/README.md b/leetcode/1115.Print-FooBar-Alternately/README.md new file mode 100755 index 000000000..fa88139ff --- /dev/null +++ b/leetcode/1115.Print-FooBar-Alternately/README.md @@ -0,0 +1,51 @@ +# [1115. Print FooBar Alternately](https://leetcode.com/problems/print-foobar-alternately/) + +## 题目 + +Suppose you are given the following code: + +```java +class FooBar { + public void foo() { + for (int i = 0; i < n; i++) { + print("foo"); + } + } + + public void bar() { + for (int i = 0; i < n; i++) { + print("bar"); + } + } +} +``` + +The same instance of `FooBar` will be passed to two different threads: +- thread A will call `foo()`, while +- thread B will call `bar()`. +Modify the given program to output `"foobar"` n times. + +**Example 1:** + + Input: n = 1 + Output: "foobar" + Explanation: There are two threads being fired asynchronously. One of them calls foo(), while the other calls bar(). "foobar" is being output 1 time. + +**Example 2:** + + Input: nums = 2 + Output: "foobarfoobar" + Explanation: "foobar" is being output 2 times. + +**Constraints:** + +- `1 <= n <= 1000` + + +## 题目大意 + +实现一个可以指定次数打印“foobar”字符串的类,foo和bar由两个线程并行打印。 + +## 解题思路 + +- 限制打印顺序依赖的思路同1114题,通过Channel实现。额外增加计数字段解决打印计数问题。注意重入问题:每次打印前要检查是否超过打印次数,如超过则直接退出。