Skip to content

Merge from master #63

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

Merged
merged 11 commits into from
May 22, 2025
Merged
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
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ members = [
"problems/problems_3355",
"problems/problems_3356",
"problems/problems_LCR_103",
"problems/problems_3362",
"problems/problems_LCR_087",
]

[package]
Expand Down Expand Up @@ -646,3 +648,5 @@ solution_3024 = { path = "problems/problems_3024", features = ["solution_3024"]
solution_3355 = { path = "problems/problems_3355", features = ["solution_3355"] }
solution_3356 = { path = "problems/problems_3356", features = ["solution_3356"] }
solution_LCR_103 = { path = "problems/problems_LCR_103", features = ["solution_LCR_103"] }
solution_3362 = { path = "problems/problems_3362", features = ["solution_3362"] }
solution_LCR_087 = { path = "problems/problems_LCR_087", features = ["solution_LCR_087"] }
4 changes: 2 additions & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ new_local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.
new_local_repository(
name = "problems",
build_file = "//cpp:solution.BUILD",
path = "problems/problems_3356/",
path = "problems/problems_3362/",
)

new_local_repository(
name = "problem0",
path = "problems/problems_LCR_103/",
path = "problems/problems_LCR_087/",
build_file = "//cpp:solution.BUILD",
)
2 changes: 1 addition & 1 deletion cpp/tests/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cc_test(
name = "test_problem_LCR_103",
name = "test_problem_LCR_087",
size = "small",
srcs = [
"//cpp:TestMain.cpp",
Expand Down
4 changes: 2 additions & 2 deletions golang/problems_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package golang

import (
"leetCode/problems/problems_LCR_103"
"leetCode/problems/problems_LCR_087"
"testing"
)

func TestSolutions(t *testing.T) {
TestEach(t, "LCR_103", "problems", problemLCR_103.Solve)
TestEach(t, "LCR_087", "problems", problemLCR_087.Solve)
}
4 changes: 2 additions & 2 deletions golang/solution_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package golang

import (
problem "leetCode/problems/problems_3356"
problem "leetCode/problems/problems_3362"
"testing"
)

func TestSolution(t *testing.T) {
TestEach(t, "3356", "problems", problem.Solve)
TestEach(t, "3362", "problems", problem.Solve)
}
67 changes: 67 additions & 0 deletions interview.md
Original file line number Diff line number Diff line change
Expand Up @@ -733,3 +733,70 @@ $ go build -gcflags="-m" main.go
1. **`new` 返回指针,`make` 返回实例**。
2. **`make` 专用于引用类型,确保数据结构可用**。
3. **内存分配位置由逃逸分析决定**,`make` 创建的底层结构通常逃逸到堆。

### 并发顺序输出1到100的Go实现

这个题目要求我们使用Go语言实现一个程序,在并发环境下顺序输出1到100的数字,同时限制最多只有10个goroutine同时运行。

```go
package main

/*
并发顺序输出1到100的Go实现

这个题目要求我们使用Go语言实现一个程序,在并发环境下顺序输出1到100的数字,同时限制最多只有10个goroutine同时运行。
*/

import "sync"

// Counter 定义一个结构体来保存当前数字和锁
type Counter struct {
current int
mu sync.Mutex
}

// 定义一个函数来输出数字
func (c *Counter) printNumber(wg *sync.WaitGroup) {
//defer wg.Done() // 在函数结束时通知WaitGroup
defer func() {
if c.current > 100 {
wg.Done()
}
}()

// 获取锁
c.mu.Lock()
defer c.mu.Unlock() // 在函数结束时释放锁

// 如果当前数字小于等于100,则输出数字并增加当前数字
if c.current <= 100 {
println(c.current)
c.current++
}
}

// 定义一个函数来控制并发输出
func (c *Counter) run() {
var wg sync.WaitGroup

wg.Add(10) // 设置WaitGroup计数器为10
// 创建10个goroutine
for i := 0; i < 10; i++ {
go func() {
for {
c.printNumber(&wg) // 调用打印函数
if c.current > 100 { // 如果当前数字大于100,则退出循环
break
}
}
}()
}

wg.Wait() // 等待所有goroutine完成
}

func main() {
counter := &Counter{current: 1} // 初始化Counter结构体
counter.run() // 调用run函数开始输出数字
}
```
52 changes: 52 additions & 0 deletions multi_threading/1114/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package main

import (
"fmt"
"math/rand"
"sync"
)

type Foo struct {
muFirst *sync.Mutex
muSecond *sync.Mutex
}

func Constructor() *Foo {
muFirst := sync.Mutex{}
muSecond := sync.Mutex{}
muFirst.Lock()
muSecond.Lock()
return &Foo{&muFirst, &muSecond}
}

func (f *Foo) first(printFirst func()) {
printFirst()
f.muFirst.Unlock()
}

func (f *Foo) second(printSecond func()) {
f.muFirst.Lock()
printSecond()
f.muFirst.Unlock()
f.muSecond.Unlock()
}

func (f *Foo) third(printThird func()) {
f.muSecond.Lock()
printThird()
}

func main() {
foo := Constructor()
threads := make([]func(), 3)
wg := sync.WaitGroup{}
wg.Add(3)
threads[0] = func() { foo.first(func() { fmt.Println("first") }); wg.Done() }
threads[1] = func() { foo.second(func() { fmt.Println("second") }); wg.Done() }
threads[2] = func() { foo.third(func() { fmt.Println("third") }); wg.Done() }
rand.Shuffle(len(threads), func(i, j int) { threads[i], threads[j] = threads[j], threads[i] })
for _, thread := range threads {
go thread()
}
wg.Wait()
}
41 changes: 41 additions & 0 deletions multi_threading/1114/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import random
import threading
from typing import Callable


class Foo:
def __init__(self):
self.first_lock = threading.Lock()
self.second_lock = threading.Lock()
self.first_lock.acquire()
self.second_lock.acquire()

def first(self, printFirst: 'Callable[[], None]') -> None:
# printFirst() outputs "first". Do not change or remove this line.
printFirst()
self.first_lock.release()

def second(self, printSecond: 'Callable[[], None]') -> None:
with self.first_lock:
# printSecond() outputs "second". Do not change or remove this line.
printSecond()
self.second_lock.release()

def third(self, printThird: 'Callable[[], None]') -> None:
with self.second_lock:
# printThird() outputs "third". Do not change or remove this line.
printThird()


if __name__ == "__main__":
foo = Foo()
thread_a = threading.Thread(target=foo.first, args=(lambda: print("first"),))
thread_b = threading.Thread(target=foo.second, args=(lambda: print("second"),))
thread_c = threading.Thread(target=foo.third, args=(lambda: print("third"),))

threads = [thread_a, thread_b, thread_c]
random.shuffle(threads)
for thread in threads:
thread.start()
for thread in threads:
thread.join()
55 changes: 55 additions & 0 deletions multi_threading/1115/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package main

import "sync"

type FooBar struct {
n int
fl *sync.Mutex
bl *sync.Mutex
}

func NewFooBar(n int) *FooBar {
fl := &sync.Mutex{}
bl := &sync.Mutex{}
bl.Lock()
return &FooBar{n, fl, bl}
}

func (fb *FooBar) Foo(printFoo func()) {
for i := 0; i < fb.n; i++ {
fb.fl.Lock()
// printFoo() outputs "foo". Do not change or remove this line.
printFoo()
fb.bl.Unlock()
}
}

func (fb *FooBar) Bar(printBar func()) {
for i := 0; i < fb.n; i++ {
fb.bl.Lock()
// printBar() outputs "bar". Do not change or remove this line.
printBar()
fb.fl.Unlock()
}
}

func main() {
fooBar := NewFooBar(5)
foo := func() {
println("foo")
}
bar := func() {
println("bar")
}
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
fooBar.Foo(foo)
}()
go func() {
defer wg.Done()
fooBar.Bar(bar)
}()
wg.Wait()
}
36 changes: 36 additions & 0 deletions multi_threading/1115/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from typing import Callable
import threading

class FooBar:
def __init__(self, n):
self.n = n
self.foo_lock = threading.Lock()
self.bar_lock = threading.Lock()
self.bar_lock.acquire()

def foo(self, printFoo: 'Callable[[], None]') -> None:

for i in range(self.n):
# printFoo() outputs "foo". Do not change or remove this line.
self.foo_lock.acquire()
printFoo()
self.bar_lock.release()

def bar(self, printBar: 'Callable[[], None]') -> None:

for i in range(self.n):
# printBar() outputs "bar". Do not change or remove this line.
self.bar_lock.acquire()
printBar()
self.foo_lock.release()


if __name__ == '__main__':
n = 5
foo_bar = FooBar(n)
thread_a = threading.Thread(target=foo_bar.foo, args=(lambda: print("foo"),))
thread_b = threading.Thread(target=foo_bar.bar, args=(lambda: print("bar"),))
thread_a.start()
thread_b.start()
thread_a.join()
thread_b.join()
69 changes: 69 additions & 0 deletions multi_threading/1116/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package main

import "sync"

type ZeroEvenOdd struct {
n int
zeroLock *sync.Mutex
evenLock *sync.Mutex
oddLock *sync.Mutex
}

func NewZeroEvenOdd(n int) *ZeroEvenOdd {
zeroLock := &sync.Mutex{}
evenLock := &sync.Mutex{}
oddLock := &sync.Mutex{}
oddLock.Lock()
evenLock.Lock()
return &ZeroEvenOdd{n, zeroLock, evenLock, oddLock}
}

func (z *ZeroEvenOdd) Zero(printNumber func(int)) {
for i := 0; i < z.n; i++ {
z.zeroLock.Lock()
printNumber(0)
if i%2 == 0 {
z.oddLock.Unlock()
} else {
z.evenLock.Unlock()
}
}
}

func (z *ZeroEvenOdd) Even(printNumber func(int)) {
for i := 2; i <= z.n; i += 2 {
z.evenLock.Lock()
printNumber(i)
z.zeroLock.Unlock()
}
}

func (z *ZeroEvenOdd) Odd(printNumber func(int)) {
for i := 1; i <= z.n; i += 2 {
z.oddLock.Lock()
printNumber(i)
z.zeroLock.Unlock()
}
}

func main() {
zeo := NewZeroEvenOdd(5)
printNumber := func(n int) {
println(n)
}
wg := sync.WaitGroup{}
wg.Add(3)
go func() {
defer wg.Done()
zeo.Zero(printNumber)
}()
go func() {
defer wg.Done()
zeo.Even(printNumber)
}()
go func() {
defer wg.Done()
zeo.Odd(printNumber)
}()
wg.Wait()
}
Loading