├── .github └── workflows │ └── go_test.yml ├── .idea ├── .gitignore ├── misc.xml ├── modules.xml ├── vcs.xml └── workspace.xml ├── Code_Random_Thoughts.iml ├── Design ├── AbstractFactory │ ├── AbstractFactory_test.go │ ├── AbstrctFactory.go │ └── Note.md ├── Adapter │ ├── Adapter.go │ └── Adapter_test.go ├── Bridge │ ├── Bridge.go │ └── Bridge_test.go ├── Builder │ ├── Builder.go │ └── Builder_test.go ├── Command │ ├── Command.go │ └── Command_test.go ├── Composite │ ├── Composite.go │ └── Composite_test.go ├── Decorator │ ├── Decorator.go │ └── Decorator_test.go ├── Facade │ ├── Facade.go │ └── Facade_test.go ├── FlyWeight │ ├── FlyWeight.go │ └── FlyWeight_test.go ├── Interpreter │ ├── Interpreter.go │ └── Interpreter_test.go ├── Iterator │ ├── Iterator.go │ └── Iterator_test.go ├── Mediator │ ├── Mediator.go │ └── Mediator_test.go ├── Memento │ ├── Memento.go │ └── Memento_test.go ├── Observer │ ├── Observer.go │ └── Observer_test.go ├── Prototype │ ├── Prototype.go │ └── Prototype_test.go ├── Proxy │ ├── Proxy.go │ └── Proxy_test.go ├── ResponsibilityChain │ ├── ResponsibilityChain.go │ └── ResponsibilityChain_test.go ├── Simple │ ├── Simple.go │ └── Simple_test.go ├── Singleton │ ├── Singleton.go │ └── Singleton_test.go ├── State │ ├── State.go │ └── State_test.go ├── Strategy │ ├── Strategy.go │ └── Strategy_test.go ├── Template │ ├── Template.go │ └── Template_test.go └── Visitor │ ├── Visitor.go │ └── Visitor_test.go ├── README.md ├── day0419 ├── Day1 数组part01.md └── main │ ├── main.exe │ ├── main.go │ └── search_test.go ├── day0420 ├── Day2 数组part02.md └── main │ └── main.go ├── day0421 ├── Day3 链表part01.md └── main │ └── main.go ├── day0422 ├── Day4 链表part02.md └── main │ └── main.go ├── day0423 └── Day5.md ├── day0424 ├── Day6 哈希表part01.md └── main │ └── main.go ├── day0425 ├── Day7 哈希表part02.md └── main │ └── main.go ├── day0426 ├── Day8 字符串part01.md └── main │ └── main.go ├── day0427 ├── Day9 字符串part02.md └── main │ └── main.go ├── day0428 ├── Day10 栈与队列part01.md └── main │ └── main.go ├── day0429 ├── Day11 栈与队列part02.md └── main │ └── main.go ├── day0501 ├── Day13 栈与队列part03.md └── main │ └── main.go ├── day0502 ├── Day14 二叉树part01.md └── main │ └── main.go ├── day0503 ├── Day15二叉树part02.md └── main │ └── main.go ├── day0504 ├── Day16 二叉树part03.md └── main │ └── main.go ├── day0505 ├── Day17二叉树part04.md └── main │ └── main.go ├── day0506 ├── Day18二叉树part05.md └── main │ └── main.go ├── day0508 ├── Day20二叉树part06.md └── main │ └── main.go ├── day0509 ├── Day21二叉树part07.md └── main │ └── main.go ├── day0510 ├── Day22二叉树part08.md └── main │ └── main.go ├── day0511 ├── Day23二叉树part03.md └── main │ └── main.go ├── day0512 ├── Day24回溯算法part01.md └── main │ └── main.go ├── day0513 ├── Day25回溯算法part02.md └── main │ └── main.go ├── day0515 ├── Day27回溯算法part03.md └── main │ └── main.go ├── day0516 ├── Day28回溯算法part04.md └── main │ └── main.go ├── day0517 ├── Day29回溯算法part05.md └── main │ └── main.go ├── day0518 ├── Day30回溯算法part06.md └── main │ └── main.go ├── day0519 ├── Day31贪心算法part01.md └── main │ └── main.go ├── day0520 ├── Day32贪心算法part02.md └── main │ └── main.go ├── day0522 ├── Day34贪心算法part03.md └── main │ └── main.go ├── day0523 ├── Day35贪心算法part04.md └── main │ └── main.go ├── day0524 ├── Day36贪心算法part05.md └── main │ └── main.go ├── day0525 ├── Day37贪心算法part06.md └── main │ └── main.go ├── day0526 ├── Day38动态规划part01.md └── main │ └── main.go ├── day0527 ├── Day39动态算法part02.md └── main │ └── main.go ├── day0529 ├── Day41动态算法part03.md └── main │ └── main.go ├── day0530 ├── Day42动态算法part04.md └── main │ └── main.go ├── day0531 ├── Day43动态算法part05.md └── main │ └── main.go ├── day0601 ├── Day44动态算法part06.md └── main │ └── main.go ├── day0602 ├── Day45动态算法part07.md └── main │ └── main.go ├── day0603 ├── Day46动态算法part08.md └── main │ └── main.go ├── day0605 ├── Day48动态规划part09.md └── main │ └── main.go ├── day0606 ├── Day49动态规划part10.md └── main │ └── main.go ├── day0607 ├── Day50动态规划part11.md └── main │ └── main.go ├── day0608 ├── Day51动态规划part12.md └── main │ └── main.go ├── day0609 ├── Day52动态规划part13.md └── main │ └── main.go ├── day0610 ├── Day53动态规划part14.md └── main │ └── main.go ├── day0612 ├── Day55动态规划part15.md └── main │ └── main.go ├── day0613 ├── Day56动态规划part16.md └── main │ └── main.go ├── day0614 ├── Day57动态规划part17.md └── main │ └── main.go ├── day0615 ├── Day58单调栈part01.md └── main │ └── main.go ├── day0616 ├── Day59单调栈part02.md └── main │ └── main.go ├── day0617 ├── Day60单调栈part03.md └── main │ └── main.go ├── day0618 └── Day61 总结篇.md ├── go.mod ├── go.sum └── mypkg └── structDef.go /.github/workflows/go_test.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Go Test And Download Output 5 | 6 | on: 7 | workflow_dispatch: 8 | # push: 9 | # branches: [ "main" ] 10 | # pull_request: 11 | # branches: [ "main" ] 12 | 13 | jobs: 14 | 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - name: Set date 21 | id: set-date 22 | run: echo "::set-output name=date::$(date +%m%d)" 23 | 24 | - name: Set up Go 25 | uses: actions/setup-go@v3 26 | with: 27 | go-version: 1.19 28 | 29 | - name: Create log directory 30 | run: mkdir -p "./day${{ steps.set-date.outputs.date }}/log" 31 | 32 | # - name: Build 33 | # run: | 34 | # cd "./day${{ steps.set-date.outputs.date }}/main" 35 | # go build -o ../main . 36 | 37 | - name: Test 38 | run: | 39 | cd "./day${{ steps.set-date.outputs.date }}/main" 40 | go test -v ./... >> ../log/day${{ steps.set-date.outputs.date }}.log 41 | 42 | - name: Upload artifact 43 | uses: actions/upload-artifact@v2 44 | with: 45 | name: ${{ steps.set-date.outputs.date }}.log 46 | path: ./day${{ steps.set-date.outputs.date }}/log/day${{ steps.set-date.outputs.date }}.log 47 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Code_Random_Thoughts.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Design/AbstractFactory/AbstractFactory_test.go: -------------------------------------------------------------------------------- 1 | package AbstractFactory 2 | 3 | import "testing" 4 | 5 | func TestNewSimpleLunchFactory(t *testing.T) { 6 | factory := NewSimpleLunchFactory() 7 | food := factory.CreateFood() 8 | food.Cook() 9 | 10 | vegetable := factory.CreateVegetable() 11 | vegetable.Cook() 12 | } 13 | -------------------------------------------------------------------------------- /Design/AbstractFactory/AbstrctFactory.go: -------------------------------------------------------------------------------- 1 | package AbstractFactory 2 | 3 | import "fmt" 4 | 5 | type Lunch interface { 6 | Cook() 7 | } 8 | type Rice struct { 9 | } 10 | 11 | func (r *Rice) Cook() { 12 | fmt.Println("正在烹饪米饭") 13 | } 14 | 15 | type Tomato struct { 16 | } 17 | 18 | func (t *Tomato) Cook() { 19 | fmt.Println("正在烹饪土豆") 20 | } 21 | 22 | type LunchFactory interface { 23 | CreateFood() Lunch 24 | CreateVegetable() Lunch 25 | } 26 | 27 | type SimpleLunchFactory struct { 28 | } 29 | 30 | func NewSimpleLunchFactory() LunchFactory { 31 | return &SimpleLunchFactory{} 32 | } 33 | 34 | func (f *SimpleLunchFactory) CreateFood() Lunch { 35 | return &Rice{} 36 | } 37 | 38 | func (f *SimpleLunchFactory) CreateVegetable() Lunch { 39 | return &Tomato{} 40 | } 41 | -------------------------------------------------------------------------------- /Design/AbstractFactory/Note.md: -------------------------------------------------------------------------------- 1 | # 抽象工厂 2 | > 代码例子中具体产品是通过实现抽象产品接口实现的,还有一种方法是定义一个抽象产品struct去实现这个抽象接口,具体产品去继承这个struct。 3 | > 在这种实现方式中,我们通常会定义一个抽象产品 AbstractProduct,它是一个包含了一些共同特性的结构体,如产品名称、价格等等,并实现了 Product 接口。然后具体产品可以通过继承 AbstractProduct 并实现 Product 接口来实现自己的特定功能。下面是一个简单的示例代码: 4 | ## 抽象工厂举例 5 | ```go 6 | // 定义抽象产品接口 7 | type Product interface { 8 | GetName() string 9 | } 10 | 11 | // 定义抽象产品结构体 12 | type AbstractProduct struct { 13 | name string 14 | } 15 | 16 | func (p *AbstractProduct) GetName() string { 17 | return p.name 18 | } 19 | 20 | // 定义具体产品A 21 | type ConcreteProductA struct { 22 | AbstractProduct 23 | } 24 | 25 | // 定义具体产品B 26 | type ConcreteProductB struct { 27 | AbstractProduct 28 | } 29 | 30 | ``` 31 | 32 | ## 异同 33 | 在代码实现上,工厂模式和抽象工厂的不同主要体现在两个方面:产品层次结构和工厂接口。 34 | 35 | 1. 产品层次结构 36 | 37 | 在工厂模式中,产品的层次结构比较简单,只有一个抽象产品类和多个具体产品类。这些具体产品类都实现了同一个抽象产品类的接口,表示它们是同一种类型的产品。 38 | 39 | 在抽象工厂中,产品的层次结构比较复杂,通常包含多个抽象产品类和多个具体产品类。这些抽象产品类都定义了一些通用的属性和方法,而具体产品类则实现了这些抽象产品类的接口,并增加了一些具体的属性和方法。 40 | 41 | 2. 工厂接口 42 | 43 | 在工厂模式中,只有一个工厂接口和多个具体工厂实现。这个工厂接口定义了一个创建产品的方法,具体工厂则实现这个方法,从而创建具体的产品对象。 44 | 45 | 在抽象工厂中,有多个抽象工厂接口和多个具体工厂实现。每个抽象工厂接口都定义了一组创建产品的方法,而具体工厂则实现这些方法,从而创建多个相互关联的产品族。 46 | 47 | 下面是一个简单的示例代码,展示了工厂模式和抽象工厂的区别: 48 | ```go 49 | // 工厂模式示例代码 50 | package factory 51 | 52 | // 抽象产品类 53 | type Product interface { 54 | Name() string 55 | } 56 | 57 | // 具体产品类 58 | type ConcreteProductA struct{} 59 | 60 | func (p *ConcreteProductA) Name() string { 61 | return "Product A" 62 | } 63 | 64 | type ConcreteProductB struct{} 65 | 66 | func (p *ConcreteProductB) Name() string { 67 | return "Product B" 68 | } 69 | 70 | // 工厂接口 71 | type Factory interface { 72 | CreateProduct() Product 73 | } 74 | 75 | // 具体工厂类 76 | type ConcreteFactory struct{} 77 | 78 | func (f *ConcreteFactory) CreateProduct() Product { 79 | return &ConcreteProductA{} 80 | } 81 | 82 | // 抽象工厂示例代码 83 | package abstractfactory 84 | 85 | // 抽象产品类 86 | type Phone interface { 87 | Name() string 88 | OS() string 89 | } 90 | 91 | type Tablet interface { 92 | Name() string 93 | OS() string 94 | } 95 | 96 | // 具体产品类 97 | type IPhone struct{} 98 | 99 | func (p *IPhone) Name() string { 100 | return "iPhone" 101 | } 102 | 103 | func (p *IPhone) OS() string { 104 | return "iOS" 105 | } 106 | 107 | type IPad struct{} 108 | 109 | func (p *IPad) Name() string { 110 | return "iPad" 111 | } 112 | 113 | func (p *IPad) OS() string { 114 | return "iOS" 115 | } 116 | 117 | // 抽象工厂接口 118 | type Factory interface { 119 | CreatePhone() Phone 120 | CreateTablet() Tablet 121 | } 122 | 123 | // 具体工厂类 124 | type AppleFactory struct{} 125 | 126 | func (f *AppleFactory) CreatePhone() Phone { 127 | return &IPhone{} 128 | } 129 | 130 | func (f *AppleFactory) CreateTablet() Tablet { 131 | return &IPad{} 132 | } 133 | ``` -------------------------------------------------------------------------------- /Design/Adapter/Adapter.go: -------------------------------------------------------------------------------- 1 | package Adapter 2 | 3 | import "fmt" 4 | 5 | type Client struct { 6 | } 7 | 8 | func (c *Client) InsertLightningConnectorIntoComputer(com Computer) { 9 | fmt.Println("Client inserts Lightning connector into computer.") 10 | com.InsertIntoLightningPort() 11 | } 12 | 13 | type Computer interface { 14 | InsertIntoLightningPort() 15 | } 16 | 17 | type Mac struct { 18 | } 19 | 20 | func (m *Mac) InsertIntoLightningPort() { 21 | fmt.Println("Lightning connector is plugged into mac machine.") 22 | } 23 | 24 | type Windows struct{} 25 | 26 | func (w *Windows) insertIntoUSBPort() { 27 | fmt.Println("USB connector is plugged into windows machine.") 28 | } 29 | 30 | type WindowsAdapter struct { 31 | windowMachine *Windows 32 | } 33 | 34 | func (w *WindowsAdapter) InsertIntoLightningPort() { 35 | fmt.Println("Adapter converts Lightning signal to USB.") 36 | w.windowMachine.insertIntoUSBPort() 37 | } 38 | -------------------------------------------------------------------------------- /Design/Adapter/Adapter_test.go: -------------------------------------------------------------------------------- 1 | package Adapter 2 | 3 | import "testing" 4 | 5 | func TestWindowsAdapter_InsertIntoLightningPort(t *testing.T) { 6 | client := &Client{} 7 | mac := &Mac{} 8 | 9 | client.InsertLightningConnectorIntoComputer(mac) 10 | 11 | windowsMachine := &Windows{} 12 | windowsMachineAdapter := &WindowsAdapter{ 13 | windowMachine: windowsMachine, 14 | } 15 | 16 | client.InsertLightningConnectorIntoComputer(windowsMachineAdapter) 17 | } 18 | -------------------------------------------------------------------------------- /Design/Bridge/Bridge.go: -------------------------------------------------------------------------------- 1 | package Bridge 2 | 3 | import "fmt" 4 | 5 | type Draw interface { 6 | DrawCircle(radius, x, y int) 7 | } 8 | type RedCircle struct { 9 | } 10 | 11 | func (c *RedCircle) DrawCircle(radius, x, y int) { 12 | fmt.Printf("画红圆半径%d 横坐标%d 纵坐标%d\n", radius, x, y) 13 | } 14 | 15 | type YellowCircle struct { 16 | } 17 | 18 | func (c *YellowCircle) DrawCircle(radius, x, y int) { 19 | fmt.Printf("画黄圆半径%d 横坐标%d 纵坐标%d\n", radius, x, y) 20 | } 21 | 22 | type Shape struct { 23 | draw Draw 24 | } 25 | 26 | func (s *Shape) Shape(d Draw) { 27 | s.draw = d 28 | } 29 | 30 | type Circle struct { 31 | shape Shape 32 | x int 33 | y int 34 | radius int 35 | } 36 | 37 | func (c *Circle) Constructor(x, y, radius int, draw Draw) { 38 | c.x = x 39 | c.y = y 40 | c.radius = radius 41 | c.shape.Shape(draw) 42 | } 43 | func (c *Circle) Draw() { 44 | c.shape.draw.DrawCircle(c.radius, c.x, c.y) 45 | } 46 | -------------------------------------------------------------------------------- /Design/Bridge/Bridge_test.go: -------------------------------------------------------------------------------- 1 | package Bridge 2 | 3 | import "testing" 4 | 5 | func TestCircle_Draw(t *testing.T) { 6 | red := Circle{} 7 | red.Constructor(2, 5, 3, &RedCircle{}) 8 | red.Draw() 9 | 10 | yellow := Circle{} 11 | yellow.Constructor(6, 8, 10, &YellowCircle{}) 12 | yellow.Draw() 13 | } 14 | -------------------------------------------------------------------------------- /Design/Builder/Builder.go: -------------------------------------------------------------------------------- 1 | package Builder 2 | 3 | type Builder interface { 4 | Build() 5 | } 6 | 7 | type ConcreteBuilder struct { 8 | built bool 9 | } 10 | 11 | func NewConcreteBuilder() ConcreteBuilder { 12 | return ConcreteBuilder{built: false} 13 | } 14 | 15 | func (b *ConcreteBuilder) Build() { 16 | b.built = true 17 | } 18 | 19 | type Director struct { 20 | builder Builder 21 | } 22 | 23 | func NewDirector(b Builder) Director { 24 | return Director{builder: b} 25 | } 26 | 27 | func (d *Director) Construct() { 28 | d.builder.Build() 29 | } 30 | 31 | type Product struct { 32 | Built bool 33 | } 34 | 35 | func (b *ConcreteBuilder) GetResult() Product { 36 | return Product{Built: b.built} 37 | } 38 | -------------------------------------------------------------------------------- /Design/Builder/Builder_test.go: -------------------------------------------------------------------------------- 1 | package Builder 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestConcreteBuilder_GetResult(t *testing.T) { 9 | builder := NewConcreteBuilder() 10 | director := NewDirector(&builder) 11 | director.Construct() 12 | product := builder.GetResult() 13 | fmt.Println(product.Built) 14 | } 15 | -------------------------------------------------------------------------------- /Design/Command/Command.go: -------------------------------------------------------------------------------- 1 | package Command 2 | 3 | import "fmt" 4 | 5 | type Command interface { 6 | Execute() 7 | } 8 | 9 | type ConcreteCommand struct { 10 | receiver *Receiver 11 | } 12 | 13 | func (c *ConcreteCommand) Execute() { 14 | c.receiver.Action() 15 | } 16 | 17 | type Receiver struct { 18 | name string 19 | } 20 | 21 | func (r *Receiver) Action() { 22 | fmt.Println("接收者", r.name, "正在执行命令") 23 | } 24 | 25 | type Invoker struct { 26 | command Command 27 | } 28 | 29 | func (i *Invoker) SetCommand(c Command) { 30 | i.command = c 31 | } 32 | 33 | func (i *Invoker) ExecuteCommand() { 34 | i.command.Execute() 35 | } 36 | -------------------------------------------------------------------------------- /Design/Command/Command_test.go: -------------------------------------------------------------------------------- 1 | package Command 2 | 3 | import "testing" 4 | 5 | func TestInvoker_ExecuteCommand(t *testing.T) { 6 | receiver := &Receiver{name: "小张"} 7 | command := &ConcreteCommand{receiver} 8 | invoker := &Invoker{} 9 | invoker.SetCommand(command) 10 | invoker.ExecuteCommand() 11 | } 12 | -------------------------------------------------------------------------------- /Design/Composite/Composite.go: -------------------------------------------------------------------------------- 1 | package Composite 2 | 3 | import "fmt" 4 | 5 | type Component interface { 6 | search(string) 7 | } 8 | 9 | type File struct { 10 | name string 11 | } 12 | 13 | func (f *File) search(keyword string) { 14 | fmt.Printf("Searching for keyword %s in file %s\n", keyword, f.name) 15 | } 16 | 17 | func (f *File) getName() string { 18 | return f.name 19 | } 20 | 21 | type Folder struct { 22 | components []Component 23 | name string 24 | } 25 | 26 | func (f *Folder) search(keyword string) { 27 | fmt.Printf("Serching recursively for keyword %s in folder %s\n", keyword, f.name) 28 | for _, composite := range f.components { 29 | composite.search(keyword) 30 | } 31 | } 32 | 33 | func (f *Folder) add(c Component) { 34 | f.components = append(f.components, c) 35 | } 36 | -------------------------------------------------------------------------------- /Design/Composite/Composite_test.go: -------------------------------------------------------------------------------- 1 | package Composite 2 | 3 | import "testing" 4 | 5 | func TestComposite(t *testing.T) { 6 | file1 := &File{name: "File1"} 7 | file2 := &File{name: "File2"} 8 | file3 := &File{name: "File3"} 9 | 10 | folder1 := &Folder{ 11 | name: "Folder1", 12 | } 13 | 14 | folder1.add(file1) 15 | 16 | folder2 := &Folder{ 17 | name: "Folder2", 18 | } 19 | folder2.add(file2) 20 | folder2.add(file3) 21 | folder2.add(folder1) 22 | 23 | folder2.search("rose") 24 | } 25 | -------------------------------------------------------------------------------- /Design/Decorator/Decorator.go: -------------------------------------------------------------------------------- 1 | package Decorator 2 | 3 | type IPizza interface { 4 | getPrice() int 5 | } 6 | 7 | type VeggieMania struct { 8 | } 9 | 10 | func (p *VeggieMania) getPrice() int { 11 | return 15 12 | } 13 | 14 | type TomatoTopping struct { 15 | pizza IPizza 16 | } 17 | 18 | func (c *TomatoTopping) getPrice() int { 19 | pizzaPrice := c.pizza.getPrice() 20 | return pizzaPrice + 7 21 | } 22 | 23 | type CheeseTopping struct { 24 | pizza IPizza 25 | } 26 | 27 | func (c *CheeseTopping) getPrice() int { 28 | pizzaPrice := c.pizza.getPrice() 29 | return pizzaPrice + 10 30 | } 31 | -------------------------------------------------------------------------------- /Design/Decorator/Decorator_test.go: -------------------------------------------------------------------------------- 1 | package Decorator 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestPizza(t *testing.T) { 9 | pizza := &VeggieMania{} 10 | 11 | //Add cheese topping 12 | pizzaWithCheese := &CheeseTopping{ 13 | pizza: pizza, 14 | } 15 | 16 | //Add tomato topping 17 | pizzaWithCheeseAndTomato := &TomatoTopping{ 18 | pizza: pizzaWithCheese, 19 | } 20 | 21 | fmt.Printf("Price of veggeMania with tomato and cheese topping is %d\n", 22 | pizzaWithCheeseAndTomato.getPrice()) 23 | } 24 | -------------------------------------------------------------------------------- /Design/Facade/Facade.go: -------------------------------------------------------------------------------- 1 | package Facade 2 | 3 | import "fmt" 4 | 5 | type CarModel struct { 6 | } 7 | 8 | func NewCarModel() *CarModel { 9 | return &CarModel{} 10 | } 11 | func (m *CarModel) SetModel() { 12 | fmt.Println("设置汽车中") 13 | } 14 | 15 | type CarEngine struct { 16 | } 17 | 18 | func NewCarEngine() *CarEngine { 19 | return &CarEngine{} 20 | } 21 | func (e CarEngine) SetEngine() { 22 | fmt.Println("设置引擎中") 23 | } 24 | 25 | type CarBody struct { 26 | } 27 | 28 | func NewCarBody() *CarBody { 29 | return &CarBody{} 30 | } 31 | func (e CarBody) SetBody() { 32 | fmt.Println("设置外观中") 33 | } 34 | 35 | type CarFacade struct { 36 | model CarModel 37 | engine CarEngine 38 | body CarBody 39 | } 40 | 41 | func NewCarFacade() *CarFacade { 42 | return &CarFacade{ 43 | model: CarModel{}, 44 | engine: CarEngine{}, 45 | body: CarBody{}, 46 | } 47 | } 48 | 49 | func (f *CarFacade) CreateCompleteCar() { 50 | f.model.SetModel() 51 | f.engine.SetEngine() 52 | f.body.SetBody() 53 | } 54 | -------------------------------------------------------------------------------- /Design/Facade/Facade_test.go: -------------------------------------------------------------------------------- 1 | package Facade 2 | 3 | import "testing" 4 | 5 | func TestCarFacade_CreateCompleteCar(t *testing.T) { 6 | f := NewCarFacade() 7 | f.CreateCompleteCar() 8 | } 9 | -------------------------------------------------------------------------------- /Design/FlyWeight/FlyWeight.go: -------------------------------------------------------------------------------- 1 | package FlyWeight 2 | 3 | import "fmt" 4 | 5 | const ( 6 | //TerroristDressType terrorist dress type 7 | TerroristDressType = "tDress" 8 | //CounterTerrroristDressType terrorist dress type 9 | CounterTerrroristDressType = "ctDress" 10 | ) 11 | 12 | var ( 13 | dressFactorySingleInstance = &DressFactory{ 14 | dressMap: make(map[string]Dress), 15 | } 16 | ) 17 | 18 | type DressFactory struct { 19 | dressMap map[string]Dress 20 | } 21 | 22 | func (d *DressFactory) getDressByType(dressType string) (Dress, error) { 23 | if d.dressMap[dressType] != nil { 24 | return d.dressMap[dressType], nil 25 | } 26 | 27 | if dressType == TerroristDressType { 28 | d.dressMap[dressType] = newTerroristDress() 29 | return d.dressMap[dressType], nil 30 | } 31 | if dressType == CounterTerrroristDressType { 32 | d.dressMap[dressType] = newCounterTerroristDress() 33 | return d.dressMap[dressType], nil 34 | } 35 | 36 | return nil, fmt.Errorf("Wrong dress type passed") 37 | } 38 | 39 | func getDressFactorySingleInstance() *DressFactory { 40 | return dressFactorySingleInstance 41 | } 42 | 43 | type Dress interface { 44 | getColor() string 45 | } 46 | 47 | type TerroristDress struct { 48 | color string 49 | } 50 | 51 | func (t *TerroristDress) getColor() string { 52 | return t.color 53 | } 54 | 55 | func newTerroristDress() *TerroristDress { 56 | return &TerroristDress{color: "red"} 57 | } 58 | 59 | type CounterTerroristDress struct { 60 | color string 61 | } 62 | 63 | func (c *CounterTerroristDress) getColor() string { 64 | return c.color 65 | } 66 | 67 | func newCounterTerroristDress() *CounterTerroristDress { 68 | return &CounterTerroristDress{color: "green"} 69 | } 70 | 71 | type Player struct { 72 | dress Dress 73 | playerType string 74 | lat int 75 | long int 76 | } 77 | 78 | func newPlayer(playerType, dressType string) *Player { 79 | dress, _ := getDressFactorySingleInstance().getDressByType(dressType) 80 | return &Player{ 81 | playerType: playerType, 82 | dress: dress, 83 | } 84 | } 85 | 86 | func (p *Player) newLocation(lat, long int) { 87 | p.lat = lat 88 | p.long = long 89 | } 90 | 91 | type game struct { 92 | terrorists []*Player 93 | counterTerrorists []*Player 94 | } 95 | 96 | func newGame() *game { 97 | return &game{ 98 | terrorists: make([]*Player, 1), 99 | counterTerrorists: make([]*Player, 1), 100 | } 101 | } 102 | 103 | func (c *game) addTerrorist(dressType string) { 104 | player := newPlayer("T", dressType) 105 | c.terrorists = append(c.terrorists, player) 106 | return 107 | } 108 | 109 | func (c *game) addCounterTerrorist(dressType string) { 110 | player := newPlayer("CT", dressType) 111 | c.counterTerrorists = append(c.counterTerrorists, player) 112 | return 113 | } 114 | -------------------------------------------------------------------------------- /Design/FlyWeight/FlyWeight_test.go: -------------------------------------------------------------------------------- 1 | package FlyWeight 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestFlyWeight(t *testing.T) { 9 | game := newGame() 10 | 11 | //Add Terrorist 12 | game.addTerrorist(TerroristDressType) 13 | game.addTerrorist(TerroristDressType) 14 | game.addTerrorist(TerroristDressType) 15 | game.addTerrorist(TerroristDressType) 16 | 17 | //Add CounterTerrorist 18 | game.addCounterTerrorist(CounterTerrroristDressType) 19 | game.addCounterTerrorist(CounterTerrroristDressType) 20 | game.addCounterTerrorist(CounterTerrroristDressType) 21 | 22 | dressFactoryInstance := getDressFactorySingleInstance() 23 | 24 | for dressType, dress := range dressFactoryInstance.dressMap { 25 | fmt.Printf("DressColorType: %s\nDressColor: %s\n", dressType, dress.getColor()) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Design/Interpreter/Interpreter.go: -------------------------------------------------------------------------------- 1 | package Interpreter 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | // Expression 定义抽象表达式接口 9 | type Expression interface { 10 | Interpret() int 11 | } 12 | 13 | // NumberExpression 定义终结符表达式 14 | type NumberExpression struct { 15 | number int 16 | } 17 | 18 | func (n *NumberExpression) Interpret() int { 19 | return n.number 20 | } 21 | 22 | // PlusExpression 定义非终结符表达式 23 | type PlusExpression struct { 24 | left Expression 25 | right Expression 26 | } 27 | 28 | func (p *PlusExpression) Interpret() int { 29 | return p.left.Interpret() + p.right.Interpret() 30 | } 31 | 32 | type MinusExpression struct { 33 | left Expression 34 | right Expression 35 | } 36 | 37 | func (m *MinusExpression) Interpret() int { 38 | return m.left.Interpret() - m.right.Interpret() 39 | } 40 | 41 | // Context 定义环境 42 | type Context struct { 43 | expressionStack []Expression 44 | } 45 | 46 | func (c *Context) PushExpression(expr Expression) { 47 | c.expressionStack = append(c.expressionStack, expr) 48 | } 49 | 50 | func (c *Context) PopExpression() Expression { 51 | if len(c.expressionStack) > 0 { 52 | expr := c.expressionStack[len(c.expressionStack)-1] 53 | c.expressionStack = c.expressionStack[:len(c.expressionStack)-1] 54 | return expr 55 | } 56 | return nil 57 | } 58 | 59 | // Interpreter 定义解释器 60 | type Interpreter struct { 61 | context *Context 62 | } 63 | 64 | func NewInterpreter() *Interpreter { 65 | return &Interpreter{&Context{}} 66 | } 67 | 68 | func (i *Interpreter) Interpret(expression string) int { 69 | tokens := strings.Split(expression, " ") 70 | var output []string 71 | var operators []string 72 | for _, token := range tokens { 73 | if _, err := strconv.Atoi(token); err == nil { 74 | output = append(output, token) 75 | } else { 76 | switch token { 77 | case "+", "-": 78 | for len(operators) > 0 && (operators[len(operators)-1] == "+" || operators[len(operators)-1] == "-") { 79 | output = append(output, operators[len(operators)-1]) 80 | operators = operators[:len(operators)-1] 81 | } 82 | operators = append(operators, token) 83 | case "(", ")": 84 | if token == "(" { 85 | operators = append(operators, token) 86 | } else { 87 | for operators[len(operators)-1] != "(" { 88 | output = append(output, operators[len(operators)-1]) 89 | operators = operators[:len(operators)-1] 90 | } 91 | operators = operators[:len(operators)-1] 92 | } 93 | } 94 | } 95 | } 96 | for len(operators) > 0 { 97 | output = append(output, operators[len(operators)-1]) 98 | operators = operators[:len(operators)-1] 99 | } 100 | 101 | for _, token := range output { 102 | if n, err := strconv.Atoi(token); err == nil { 103 | i.context.PushExpression(&NumberExpression{n}) 104 | } else { 105 | var left, right Expression 106 | right = i.context.PopExpression() 107 | left = i.context.PopExpression() 108 | switch token { 109 | case "+": 110 | i.context.PushExpression(&PlusExpression{left, right}) 111 | case "-": 112 | i.context.PushExpression(&MinusExpression{left, right}) 113 | } 114 | } 115 | } 116 | result := i.context.PopExpression() 117 | return result.Interpret() 118 | } 119 | -------------------------------------------------------------------------------- /Design/Interpreter/Interpreter_test.go: -------------------------------------------------------------------------------- 1 | package Interpreter 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestAdd_Interpret(t *testing.T) { 9 | expression := "11 + 2 - 6" 10 | interpreter := NewInterpreter() 11 | result := interpreter.Interpret(expression) 12 | fmt.Printf("%s = %d\n", expression, result) 13 | } 14 | -------------------------------------------------------------------------------- /Design/Iterator/Iterator.go: -------------------------------------------------------------------------------- 1 | package Iterator 2 | 3 | type Collection interface { 4 | createIterator() Iterator 5 | } 6 | 7 | type Iterator interface { 8 | hasNext() bool 9 | getNext() *User 10 | } 11 | type User struct { 12 | name string 13 | age int 14 | } 15 | 16 | type UserIterator struct { 17 | index int 18 | users []*User 19 | } 20 | 21 | func (i *UserIterator) hasNext() bool { 22 | if i.index < len(i.users) { 23 | return true 24 | } 25 | return false 26 | } 27 | 28 | func (i *UserIterator) getNext() *User { 29 | if i.hasNext() { 30 | user := i.users[i.index] 31 | i.index++ 32 | return user 33 | } 34 | return nil 35 | } 36 | 37 | type UserCollection struct { 38 | users []*User 39 | } 40 | 41 | func (c UserCollection) createIterator() Iterator { 42 | return &UserIterator{ 43 | index: 0, 44 | users: c.users, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Design/Iterator/Iterator_test.go: -------------------------------------------------------------------------------- 1 | package Iterator 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestCommand(t *testing.T) { 9 | user1 := &User{ 10 | name: "a", 11 | age: 30, 12 | } 13 | user2 := &User{ 14 | name: "b", 15 | age: 20, 16 | } 17 | 18 | userCollection := &UserCollection{ 19 | users: []*User{user1, user2}, 20 | } 21 | 22 | iterator := userCollection.createIterator() 23 | 24 | for iterator.hasNext() { 25 | user := iterator.getNext() 26 | fmt.Printf("User is %+v\n", user) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Design/Mediator/Mediator.go: -------------------------------------------------------------------------------- 1 | package Mediator 2 | 3 | import "fmt" 4 | 5 | type Train interface { 6 | arrive() 7 | depart() 8 | permitArrival() 9 | } 10 | 11 | type Mediator interface { 12 | canArrive(Train) bool 13 | notifyAboutDeparture() 14 | } 15 | 16 | type StationManager struct { 17 | isPlatformFree bool 18 | trainQueue []Train 19 | } 20 | 21 | func newStationManger() *StationManager { 22 | return &StationManager{ 23 | isPlatformFree: true, 24 | } 25 | } 26 | 27 | func (s *StationManager) canArrive(t Train) bool { 28 | if s.isPlatformFree { 29 | s.isPlatformFree = false 30 | return true 31 | } 32 | s.trainQueue = append(s.trainQueue, t) 33 | return false 34 | } 35 | 36 | func (s *StationManager) notifyAboutDeparture() { 37 | if !s.isPlatformFree { 38 | s.isPlatformFree = true 39 | } 40 | if len(s.trainQueue) > 0 { 41 | firstTrainInQueue := s.trainQueue[0] 42 | s.trainQueue = s.trainQueue[1:] 43 | firstTrainInQueue.permitArrival() 44 | } 45 | } 46 | 47 | type PassengerTrain struct { 48 | mediator Mediator 49 | } 50 | 51 | func (g *PassengerTrain) arrive() { 52 | if !g.mediator.canArrive(g) { 53 | fmt.Println("PassengerTrain: Arrival blocked, waiting") 54 | return 55 | } 56 | fmt.Println("PassengerTrain: Arrived") 57 | } 58 | 59 | func (g *PassengerTrain) depart() { 60 | fmt.Println("PassengerTrain: Leaving") 61 | g.mediator.notifyAboutDeparture() 62 | } 63 | 64 | func (g *PassengerTrain) permitArrival() { 65 | fmt.Println("PassengerTrain: Arrival permitted, arriving") 66 | g.arrive() 67 | } 68 | 69 | type FreightTrain struct { 70 | mediator Mediator 71 | } 72 | 73 | func (g *FreightTrain) arrive() { 74 | if !g.mediator.canArrive(g) { 75 | fmt.Println("FreightTrain: Arrival blocked, waiting") 76 | return 77 | } 78 | fmt.Println("FreightTrain: Arrived") 79 | } 80 | 81 | func (g *FreightTrain) depart() { 82 | fmt.Println("FreightTrain: Leaving") 83 | g.mediator.notifyAboutDeparture() 84 | } 85 | 86 | func (g *FreightTrain) permitArrival() { 87 | fmt.Println("FreightTrain: Arrival permitted") 88 | g.arrive() 89 | } 90 | -------------------------------------------------------------------------------- /Design/Mediator/Mediator_test.go: -------------------------------------------------------------------------------- 1 | package Mediator 2 | 3 | import "testing" 4 | 5 | func TestTrain(t *testing.T) { 6 | stationManager := newStationManger() 7 | 8 | passengerTrain := &PassengerTrain{ 9 | mediator: stationManager, 10 | } 11 | freightTrain := &FreightTrain{ 12 | mediator: stationManager, 13 | } 14 | 15 | passengerTrain.arrive() 16 | freightTrain.arrive() 17 | passengerTrain.depart() 18 | } 19 | -------------------------------------------------------------------------------- /Design/Memento/Memento.go: -------------------------------------------------------------------------------- 1 | package Memento 2 | 3 | type Memento struct { 4 | state string 5 | } 6 | 7 | func (m *Memento) getSavedState() string { 8 | return m.state 9 | } 10 | 11 | type Originator struct { 12 | state string 13 | } 14 | 15 | func (e *Originator) createMemento() *Memento { 16 | return &Memento{state: e.state} 17 | } 18 | 19 | func (e *Originator) restoreMemento(m *Memento) { 20 | e.state = m.getSavedState() 21 | } 22 | 23 | func (e *Originator) setState(state string) { 24 | e.state = state 25 | } 26 | 27 | func (e *Originator) getState() string { 28 | return e.state 29 | } 30 | 31 | type Caretaker struct { 32 | mementoArray []*Memento 33 | } 34 | 35 | func (c *Caretaker) addMemento(m *Memento) { 36 | c.mementoArray = append(c.mementoArray, m) 37 | } 38 | 39 | func (c *Caretaker) getMemento(index int) *Memento { 40 | return c.mementoArray[index] 41 | } 42 | -------------------------------------------------------------------------------- /Design/Memento/Memento_test.go: -------------------------------------------------------------------------------- 1 | package Memento 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestMemento(t *testing.T) { 9 | caretaker := &Caretaker{ 10 | mementoArray: make([]*Memento, 0), 11 | } 12 | 13 | originator := &Originator{ 14 | state: "A", 15 | } 16 | 17 | fmt.Printf("Originator Current State: %s\n", originator.getState()) 18 | caretaker.addMemento(originator.createMemento()) 19 | 20 | originator.setState("B") 21 | fmt.Printf("Originator Current State: %s\n", originator.getState()) 22 | caretaker.addMemento(originator.createMemento()) 23 | 24 | originator.setState("C") 25 | fmt.Printf("Originator Current State: %s\n", originator.getState()) 26 | caretaker.addMemento(originator.createMemento()) 27 | 28 | originator.restoreMemento(caretaker.getMemento(1)) 29 | fmt.Printf("Restored to State: %s\n", originator.getState()) 30 | 31 | originator.restoreMemento(caretaker.getMemento(0)) 32 | fmt.Printf("Restored to State: %s\n", originator.getState()) 33 | } 34 | -------------------------------------------------------------------------------- /Design/Observer/Observer.go: -------------------------------------------------------------------------------- 1 | package Observer 2 | 3 | import "fmt" 4 | 5 | type Subject interface { 6 | register(observer Observer) 7 | deregister(observer Observer) 8 | notifyAll() 9 | } 10 | type Item struct { 11 | observerList []Observer 12 | name string 13 | inStock bool 14 | } 15 | 16 | func newItem(name string) *Item { 17 | return &Item{ 18 | name: name, 19 | } 20 | } 21 | func (i *Item) updateAvailability() { 22 | fmt.Printf("Item %s is now in stock\n", i.name) 23 | i.inStock = true 24 | i.notifyAll() 25 | } 26 | func (i *Item) register(o Observer) { 27 | i.observerList = append(i.observerList, o) 28 | } 29 | 30 | func (i *Item) deregister(o Observer) { 31 | i.observerList = removeFromSlice(i.observerList, o) 32 | } 33 | 34 | func (i *Item) notifyAll() { 35 | for _, observer := range i.observerList { 36 | observer.update(i.name) 37 | } 38 | } 39 | 40 | func removeFromSlice(observerList []Observer, observerToRemove Observer) []Observer { 41 | observerListLength := len(observerList) 42 | for i, observer := range observerList { 43 | if observerToRemove.getID() == observer.getID() { 44 | observerList[observerListLength-1], observerList[i] = observerList[i], observerList[observerListLength-1] 45 | return observerList[:observerListLength-1] 46 | } 47 | } 48 | return observerList 49 | } 50 | 51 | type Observer interface { 52 | update(string) 53 | getID() string 54 | } 55 | type Customer struct { 56 | id string 57 | } 58 | 59 | func (c *Customer) update(itemName string) { 60 | fmt.Printf("Sending email to customer %s for item %s\n", c.id, itemName) 61 | } 62 | 63 | func (c *Customer) getID() string { 64 | return c.id 65 | } 66 | -------------------------------------------------------------------------------- /Design/Observer/Observer_test.go: -------------------------------------------------------------------------------- 1 | package Observer 2 | 3 | import "testing" 4 | 5 | func TestObserver(t *testing.T) { 6 | shirtItem := newItem("Nike Shirt") 7 | 8 | observerFirst := &Customer{id: "abc@gmail.com"} 9 | observerSecond := &Customer{id: "xyz@gmail.com"} 10 | 11 | shirtItem.register(observerFirst) 12 | shirtItem.register(observerSecond) 13 | 14 | shirtItem.updateAvailability() 15 | } 16 | -------------------------------------------------------------------------------- /Design/Prototype/Prototype.go: -------------------------------------------------------------------------------- 1 | package Prototype 2 | 3 | import "fmt" 4 | 5 | type Inode interface { 6 | print(string) 7 | clone() Inode 8 | } 9 | type File struct { 10 | name string 11 | } 12 | 13 | func (f *File) print(indentation string) { 14 | fmt.Println(indentation + f.name) 15 | } 16 | 17 | func (f *File) clone() Inode { 18 | return &File{name: f.name + "_clone"} 19 | } 20 | 21 | type Folder struct { 22 | children []Inode 23 | name string 24 | } 25 | 26 | func (f *Folder) print(indentation string) { 27 | fmt.Println(indentation + f.name) 28 | for _, i := range f.children { 29 | i.print(indentation + indentation) 30 | } 31 | } 32 | 33 | func (f *Folder) clone() Inode { 34 | cloneFolder := &Folder{name: f.name + "_clone"} 35 | var tempChildren []Inode 36 | for _, i := range f.children { 37 | copy := i.clone() 38 | tempChildren = append(tempChildren, copy) 39 | } 40 | cloneFolder.children = tempChildren 41 | return cloneFolder 42 | } 43 | -------------------------------------------------------------------------------- /Design/Prototype/Prototype_test.go: -------------------------------------------------------------------------------- 1 | package Prototype 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestClone(t *testing.T) { 9 | file1 := &File{name: "File1"} 10 | file2 := &File{name: "File2"} 11 | file3 := &File{name: "File3"} 12 | 13 | folder1 := &Folder{ 14 | children: []Inode{file1}, 15 | name: "Folder1", 16 | } 17 | 18 | folder2 := &Folder{ 19 | children: []Inode{folder1, file2, file3}, 20 | name: "Folder2", 21 | } 22 | fmt.Println("\nPrinting hierarchy for Folder2") 23 | folder2.print(" ") 24 | 25 | cloneFolder := folder2.clone() 26 | fmt.Println("\nPrinting hierarchy for clone Folder") 27 | cloneFolder.print(" ") 28 | } 29 | -------------------------------------------------------------------------------- /Design/Proxy/Proxy.go: -------------------------------------------------------------------------------- 1 | package Proxy 2 | 3 | type server interface { 4 | handleRequest(string, string) (int, string) 5 | } 6 | type Nginx struct { 7 | application *Application 8 | maxAllowedRequest int 9 | rateLimiter map[string]int 10 | } 11 | 12 | func newNginxServer() *Nginx { 13 | return &Nginx{ 14 | application: &Application{}, 15 | maxAllowedRequest: 2, 16 | rateLimiter: make(map[string]int), 17 | } 18 | } 19 | 20 | func (n *Nginx) handleRequest(url, method string) (int, string) { 21 | allowed := n.checkRateLimiting(url) 22 | if !allowed { 23 | return 403, "Not Allowed" 24 | } 25 | return n.application.handleRequest(url, method) 26 | } 27 | 28 | func (n *Nginx) checkRateLimiting(url string) bool { 29 | if n.rateLimiter[url] == 0 { 30 | n.rateLimiter[url] = 1 31 | } 32 | if n.rateLimiter[url] > n.maxAllowedRequest { 33 | return false 34 | } 35 | n.rateLimiter[url] = n.rateLimiter[url] + 1 36 | return true 37 | } 38 | 39 | type Application struct { 40 | } 41 | 42 | func (a *Application) handleRequest(url, method string) (int, string) { 43 | if url == "/app/status" && method == "GET" { 44 | return 200, "Ok" 45 | } 46 | 47 | if url == "/create/user" && method == "POST" { 48 | return 201, "User Created" 49 | } 50 | return 404, "Not Ok" 51 | } 52 | -------------------------------------------------------------------------------- /Design/Proxy/Proxy_test.go: -------------------------------------------------------------------------------- 1 | package Proxy 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestNginx(t *testing.T) { 9 | nginxServer := newNginxServer() 10 | appStatusURL := "/app/status" 11 | createuserURL := "/create/user" 12 | 13 | httpCode, body := nginxServer.handleRequest(appStatusURL, "GET") 14 | fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) 15 | 16 | httpCode, body = nginxServer.handleRequest(appStatusURL, "GET") 17 | fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) 18 | 19 | httpCode, body = nginxServer.handleRequest(appStatusURL, "GET") 20 | fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) 21 | 22 | httpCode, body = nginxServer.handleRequest(createuserURL, "POST") 23 | fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) 24 | 25 | httpCode, body = nginxServer.handleRequest(createuserURL, "GET") 26 | fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) 27 | } 28 | -------------------------------------------------------------------------------- /Design/ResponsibilityChain/ResponsibilityChain.go: -------------------------------------------------------------------------------- 1 | package ResponsibilityChain 2 | 3 | import "fmt" 4 | 5 | type Department interface { 6 | execute(*Patient) 7 | setNext(Department) 8 | } 9 | 10 | type Patient struct { 11 | name string 12 | registrationDone bool 13 | doctorCheckUpDone bool 14 | medicineDone bool 15 | paymentDone bool 16 | } 17 | 18 | type Reception struct { 19 | next Department 20 | } 21 | 22 | func (r *Reception) execute(p *Patient) { 23 | if p.registrationDone { 24 | fmt.Println("Patient registration already done") 25 | r.next.execute(p) 26 | return 27 | } 28 | fmt.Println("Reception registering patient") 29 | p.registrationDone = true 30 | r.next.execute(p) 31 | } 32 | 33 | func (r *Reception) setNext(next Department) { 34 | r.next = next 35 | } 36 | 37 | type Doctor struct { 38 | next Department 39 | } 40 | 41 | func (d *Doctor) execute(p *Patient) { 42 | if p.doctorCheckUpDone { 43 | fmt.Println("Doctor checkup already done") 44 | d.next.execute(p) 45 | return 46 | } 47 | fmt.Println("Doctor checking patient") 48 | p.doctorCheckUpDone = true 49 | d.next.execute(p) 50 | } 51 | 52 | func (d *Doctor) setNext(next Department) { 53 | d.next = next 54 | } 55 | 56 | type Medical struct { 57 | next Department 58 | } 59 | 60 | func (m *Medical) execute(p *Patient) { 61 | if p.medicineDone { 62 | fmt.Println("Medicine already given to patient") 63 | m.next.execute(p) 64 | return 65 | } 66 | fmt.Println("Medical giving medicine to patient") 67 | p.medicineDone = true 68 | m.next.execute(p) 69 | } 70 | 71 | func (m *Medical) setNext(next Department) { 72 | m.next = next 73 | } 74 | 75 | type Cashier struct { 76 | next Department 77 | } 78 | 79 | func (c *Cashier) execute(p *Patient) { 80 | if p.paymentDone { 81 | fmt.Println("Payment Done") 82 | } 83 | fmt.Println("Cashier getting money from patient patient") 84 | } 85 | 86 | func (c *Cashier) setNext(next Department) { 87 | c.next = next 88 | } 89 | -------------------------------------------------------------------------------- /Design/ResponsibilityChain/ResponsibilityChain_test.go: -------------------------------------------------------------------------------- 1 | package ResponsibilityChain 2 | 3 | import "testing" 4 | 5 | func TestPatient(t *testing.T) { 6 | cashier := &Cashier{} 7 | 8 | //Set next for medical department 9 | medical := &Medical{} 10 | medical.setNext(cashier) 11 | 12 | //Set next for doctor department 13 | doctor := &Doctor{} 14 | doctor.setNext(medical) 15 | 16 | //Set next for reception department 17 | reception := &Reception{} 18 | reception.setNext(doctor) 19 | 20 | patient := &Patient{name: "abc"} 21 | //Patient visiting 22 | reception.execute(patient) 23 | } 24 | -------------------------------------------------------------------------------- /Design/Simple/Simple.go: -------------------------------------------------------------------------------- 1 | package Simple 2 | 3 | import "fmt" 4 | 5 | type Restaurant interface { 6 | GetFood() 7 | } 8 | 9 | type LanzhouNoodles struct { 10 | } 11 | 12 | func (n LanzhouNoodles) GetFood() { 13 | fmt.Println("煮一碗兰州拉面") 14 | } 15 | 16 | type KFC struct { 17 | } 18 | 19 | func (k KFC) GetFood() { 20 | fmt.Println("制作一份疯狂星期四套餐") 21 | } 22 | 23 | func NewRestaurant(name string) Restaurant { 24 | switch name { 25 | case "L": 26 | return &LanzhouNoodles{} 27 | case "K": 28 | return &KFC{} 29 | } 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /Design/Simple/Simple_test.go: -------------------------------------------------------------------------------- 1 | package Simple 2 | 3 | import "testing" 4 | 5 | func TestNewRestaurant(t *testing.T) { 6 | NewRestaurant("K").GetFood() 7 | NewRestaurant("L").GetFood() 8 | } 9 | -------------------------------------------------------------------------------- /Design/Singleton/Singleton.go: -------------------------------------------------------------------------------- 1 | package Singleton 2 | 3 | import "sync" 4 | 5 | type singleton struct { 6 | count int 7 | } 8 | 9 | var ( 10 | instance *singleton 11 | once sync.Once 12 | ) 13 | 14 | func GetInstance() *singleton { 15 | once.Do(func() { 16 | instance = &singleton{} 17 | }) 18 | return instance 19 | } 20 | 21 | func (s *singleton) AddOne() { 22 | s.count++ 23 | } 24 | 25 | func (s *singleton) GetCount() int { 26 | return s.count 27 | } 28 | -------------------------------------------------------------------------------- /Design/Singleton/Singleton_test.go: -------------------------------------------------------------------------------- 1 | package Singleton 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | ) 7 | 8 | func TestGetInstance(t *testing.T) { 9 | // 通过GetInstance获取单例实例 10 | instance1 := GetInstance() 11 | instance2 := GetInstance() 12 | 13 | if instance1 == nil { 14 | t.Error("Expected non-nil instance, but got nil") 15 | } 16 | 17 | if instance2 == nil { 18 | t.Error("Expected non-nil instance, but got nil") 19 | } 20 | 21 | if instance1 != instance2 { 22 | t.Error("Expected same instance, but got different instances") 23 | } 24 | } 25 | 26 | func TestGetInstanceConcurrent(t *testing.T) { 27 | // 创建WaitGroup和Mutex来确保并发安全性 28 | var wg sync.WaitGroup 29 | var mu sync.Mutex 30 | 31 | // 并发获取单例实例 32 | for i := 0; i < 1000; i++ { 33 | wg.Add(1) 34 | go func() { 35 | defer wg.Done() 36 | 37 | instance := GetInstance() 38 | 39 | // 使用锁来确保单例实例的并发安全性 40 | mu.Lock() 41 | if instance == nil { 42 | t.Error("Expected non-nil instance, but got nil") 43 | } 44 | mu.Unlock() 45 | }() 46 | } 47 | 48 | wg.Wait() 49 | } 50 | -------------------------------------------------------------------------------- /Design/State/State_test.go: -------------------------------------------------------------------------------- 1 | package State 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "testing" 7 | ) 8 | 9 | func TestVending(t *testing.T) { 10 | vendingMachine := newVendingMachine(1, 10) 11 | 12 | err := vendingMachine.requestItem() 13 | if err != nil { 14 | log.Fatalf(err.Error()) 15 | } 16 | 17 | err = vendingMachine.insertMoney(10) 18 | if err != nil { 19 | log.Fatalf(err.Error()) 20 | } 21 | 22 | err = vendingMachine.dispenseItem() 23 | if err != nil { 24 | log.Fatalf(err.Error()) 25 | } 26 | 27 | fmt.Println() 28 | 29 | err = vendingMachine.addItem(2) 30 | if err != nil { 31 | log.Fatalf(err.Error()) 32 | } 33 | 34 | fmt.Println() 35 | 36 | err = vendingMachine.requestItem() 37 | if err != nil { 38 | log.Fatalf(err.Error()) 39 | } 40 | 41 | err = vendingMachine.insertMoney(10) 42 | if err != nil { 43 | log.Fatalf(err.Error()) 44 | } 45 | 46 | err = vendingMachine.dispenseItem() 47 | if err != nil { 48 | log.Fatalf(err.Error()) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Design/Strategy/Strategy.go: -------------------------------------------------------------------------------- 1 | package Strategy 2 | 3 | import "fmt" 4 | 5 | type EvictionAlgo interface { 6 | evict(c *Cache) 7 | } 8 | type Fifo struct { 9 | } 10 | 11 | func (l *Fifo) evict(c *Cache) { 12 | fmt.Println("Evicting by fifo strtegy") 13 | } 14 | 15 | type Lru struct { 16 | } 17 | 18 | func (l *Lru) evict(c *Cache) { 19 | fmt.Println("Evicting by lru strtegy") 20 | } 21 | 22 | type Lfu struct { 23 | } 24 | 25 | func (l *Lfu) evict(c *Cache) { 26 | fmt.Println("Evicting by lfu strtegy") 27 | } 28 | 29 | type Cache struct { 30 | storage map[string]string 31 | evictionAlgo EvictionAlgo 32 | capacity int 33 | maxCapacity int 34 | } 35 | 36 | func initCache(e EvictionAlgo) *Cache { 37 | storage := make(map[string]string) 38 | return &Cache{ 39 | storage: storage, 40 | evictionAlgo: e, 41 | capacity: 0, 42 | maxCapacity: 2, 43 | } 44 | } 45 | 46 | func (c *Cache) setEvictionAlgo(e EvictionAlgo) { 47 | c.evictionAlgo = e 48 | } 49 | 50 | func (c *Cache) add(key, value string) { 51 | if c.capacity == c.maxCapacity { 52 | c.evict() 53 | } 54 | c.capacity++ 55 | c.storage[key] = value 56 | } 57 | 58 | func (c *Cache) get(key string) { 59 | delete(c.storage, key) 60 | } 61 | 62 | func (c *Cache) evict() { 63 | c.evictionAlgo.evict(c) 64 | c.capacity-- 65 | } 66 | -------------------------------------------------------------------------------- /Design/Strategy/Strategy_test.go: -------------------------------------------------------------------------------- 1 | package Strategy 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestEvictionAlgo(t *testing.T) { 8 | lfu := &Lfu{} 9 | cache := initCache(lfu) 10 | 11 | cache.add("a", "1") 12 | cache.add("b", "2") 13 | 14 | cache.add("c", "3") 15 | 16 | lru := &Lru{} 17 | cache.setEvictionAlgo(lru) 18 | 19 | cache.add("d", "4") 20 | 21 | fifo := &Fifo{} 22 | cache.setEvictionAlgo(fifo) 23 | 24 | cache.add("e", "5") 25 | } 26 | -------------------------------------------------------------------------------- /Design/Template/Template.go: -------------------------------------------------------------------------------- 1 | package Template 2 | 3 | import "fmt" 4 | 5 | type IOtp interface { 6 | genRandomOTP(int) string 7 | saveOTPCache(string) 8 | getMessage(string) string 9 | sendNotification(string) error 10 | } 11 | 12 | type Otp struct { 13 | iOtp IOtp 14 | } 15 | 16 | func (o *Otp) genAndSendOTP(otpLength int) error { 17 | otp := o.iOtp.genRandomOTP(otpLength) 18 | o.iOtp.saveOTPCache(otp) 19 | message := o.iOtp.getMessage(otp) 20 | err := o.iOtp.sendNotification(message) 21 | if err != nil { 22 | return err 23 | } 24 | return nil 25 | } 26 | 27 | type Sms struct { 28 | Otp 29 | } 30 | 31 | func (s *Sms) genRandomOTP(len int) string { 32 | randomOTP := "1234" 33 | fmt.Printf("SMS: generating random otp %s\n", randomOTP) 34 | return randomOTP 35 | } 36 | func (s *Sms) saveOTPCache(otp string) { 37 | fmt.Printf("SMS: saving otp: %s to cache\n", otp) 38 | } 39 | 40 | func (s *Sms) getMessage(otp string) string { 41 | return "SMS OTP for login is " + otp 42 | } 43 | 44 | func (s *Sms) sendNotification(message string) error { 45 | fmt.Printf("SMS: sending sms: %s\n", message) 46 | return nil 47 | } 48 | 49 | type Email struct { 50 | Otp 51 | } 52 | 53 | func (s *Email) genRandomOTP(len int) string { 54 | randomOTP := "1234" 55 | fmt.Printf("EMAIL: generating random otp %s\n", randomOTP) 56 | return randomOTP 57 | } 58 | 59 | func (s *Email) saveOTPCache(otp string) { 60 | fmt.Printf("EMAIL: saving otp: %s to cache\n", otp) 61 | } 62 | 63 | func (s *Email) getMessage(otp string) string { 64 | return "EMAIL OTP for login is " + otp 65 | } 66 | 67 | func (s *Email) sendNotification(message string) error { 68 | fmt.Printf("EMAIL: sending email: %s\n", message) 69 | return nil 70 | } 71 | -------------------------------------------------------------------------------- /Design/Template/Template_test.go: -------------------------------------------------------------------------------- 1 | package Template 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestGenAndTest(t *testing.T) { 9 | smsOTP := &Sms{} 10 | o := Otp{ 11 | iOtp: smsOTP, 12 | } 13 | err := o.genAndSendOTP(4) 14 | if err != nil { 15 | return 16 | } 17 | 18 | fmt.Println("") 19 | emailOTP := &Email{} 20 | o = Otp{ 21 | iOtp: emailOTP, 22 | } 23 | err = o.genAndSendOTP(4) 24 | if err != nil { 25 | return 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Design/Visitor/Visitor.go: -------------------------------------------------------------------------------- 1 | package Visitor 2 | 3 | // Employee 定义员工结构体 4 | type Employee interface { 5 | Accept(v Visitor) 6 | GetName() string 7 | GetSalary() float64 8 | } 9 | 10 | type Manager struct { 11 | Name string 12 | Salary float64 13 | } 14 | 15 | func (m *Manager) Accept(v Visitor) { 16 | v.VisitManager(m) 17 | } 18 | 19 | func (m *Manager) GetName() string { 20 | return m.Name 21 | } 22 | 23 | func (m *Manager) GetSalary() float64 { 24 | return m.Salary 25 | } 26 | 27 | type Developer struct { 28 | Name string 29 | Salary float64 30 | } 31 | 32 | func (d *Developer) Accept(v Visitor) { 33 | v.VisitDeveloper(d) 34 | } 35 | 36 | func (d *Developer) GetName() string { 37 | return d.Name 38 | } 39 | 40 | func (d *Developer) GetSalary() float64 { 41 | return d.Salary 42 | } 43 | 44 | // Visitor 定义访问者接口 45 | type Visitor interface { 46 | VisitManager(e *Manager) 47 | VisitDeveloper(e *Developer) 48 | } 49 | 50 | // BonusVisitor 实现访问者接口 51 | type BonusVisitor struct{} 52 | 53 | func (b *BonusVisitor) VisitManager(m *Manager) { 54 | m.Salary *= 1.2 // 给经理加 20% 的奖金 55 | } 56 | 57 | func (b *BonusVisitor) VisitDeveloper(d *Developer) { 58 | d.Salary *= 1.1 // 给开发人员加 10% 的奖金 59 | } 60 | -------------------------------------------------------------------------------- /Design/Visitor/Visitor_test.go: -------------------------------------------------------------------------------- 1 | package Visitor 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestBonusVisitor_VisitManager(t *testing.T) { 9 | employees := []Employee{ 10 | &Manager{Name: "Alice", Salary: 8000}, 11 | &Developer{Name: "Bob", Salary: 5000}, 12 | } 13 | 14 | bonusVisitor := &BonusVisitor{} 15 | 16 | for _, e := range employees { 17 | e.Accept(bonusVisitor) 18 | fmt.Printf("%s's new salary: %.2f\n", e.GetName(), e.GetSalary()) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /day0419/Day1 数组part01.md: -------------------------------------------------------------------------------- 1 | # Day1 2 | 3 | ## 704.二分查找 4 | 5 | 1. 解题代码想到的是左闭右闭 6 | 7 | ```go 8 | package main 9 | 10 | func search(nums []int, target int) int { 11 | start := 0 12 | end := len(nums) - 1 13 | for { 14 | if end < start { 15 | return -1 16 | } else if nums[(end-start)/2+start] == target { 17 | return (end-start)/2 + start 18 | } 19 | if nums[(end-start)/2+start] < target { 20 | start = (end-start)/2 + start + 1 21 | } else { 22 | end = (end-start)/2 + start - 1 23 | } 24 | } 25 | } 26 | ``` 27 | 28 | 2. 利用ChatGPT生成了测试用例 29 | 30 | ```go 31 | package main 32 | 33 | import "testing" 34 | 35 | func TestSearch(t *testing.T) { 36 | // Test case 1 37 | nums1 := []int{-1, 0, 3, 5, 9, 12} 38 | target1 := 9 39 | expected1 := 4 40 | result1 := search(nums1, target1) 41 | if result1 != expected1 { 42 | t.Errorf("search(%v, %d) = %d; expected %d", nums1, target1, result1, expected1) 43 | } 44 | 45 | // Test case 2 46 | nums2 := []int{-1, 0, 3, 5, 9, 12} 47 | target2 := 2 48 | expected2 := -1 49 | result2 := search(nums2, target2) 50 | if result2 != expected2 { 51 | t.Errorf("search(%v, %d) = %d; expected %d", nums2, target2, result2, expected2) 52 | } 53 | 54 | // Test case 3 55 | nums3 := []int{1} 56 | target3 := 1 57 | expected3 := 0 58 | result3 := search(nums3, target3) 59 | if result3 != expected3 { 60 | t.Errorf("search(%v, %d) = %d; expected %d", nums3, target3, result3, expected3) 61 | } 62 | 63 | // Test case 4 64 | nums4 := []int{5, 7, 8, 9, 10} 65 | target4 := 6 66 | expected4 := -1 67 | result4 := search(nums4, target4) 68 | if result4 != expected4 { 69 | t.Errorf("search(%v, %d) = %d; expected %d", nums4, target4, result4, expected4) 70 | } 71 | } 72 | ``` 73 | 74 | ## 27.移除元素 75 | 76 | 1. 暴力解法 77 | ```go 78 | package main 79 | 80 | func removeElement(nums []int, val int) int { 81 | sum := len(nums) 82 | for i := 0; i < sum; i++ { 83 | if nums[i] == val { 84 | sum-- 85 | nums = append(nums[:i], nums[i+1:]...) 86 | i-- 87 | } 88 | } 89 | return sum 90 | } 91 | ``` 92 | 2. 双指针解法 93 | ```go 94 | package main 95 | func removeElement(nums []int, val int) int { 96 | slow := 0 97 | for i := 0; i < len(nums); i++ { 98 | if nums[i] != val { 99 | nums[slow] = nums[i] 100 | slow++ 101 | } 102 | } 103 | return slow 104 | } 105 | ``` 106 | 107 | 3. 相向双指针解法 108 | ```go 109 | package main 110 | func removeElement(nums []int, val int) int { 111 | left := 0 112 | right := len(nums) - 1 113 | for left <= right { 114 | for left <= right && nums[left] != val { 115 | left++ 116 | } 117 | for left <= right && nums[right] == val { 118 | right-- 119 | } 120 | if left < right { 121 | nums[left] = nums[right] 122 | left++ 123 | right-- 124 | } 125 | } 126 | return left 127 | } 128 | ``` -------------------------------------------------------------------------------- /day0419/main/main.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watoli/Code_Random_Thoughts/657ed431be0f607167792f53decf159c281a787c/day0419/main/main.exe -------------------------------------------------------------------------------- /day0419/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func search(nums []int, target int) int { 4 | start := 0 5 | end := len(nums) - 1 6 | for { 7 | if end < start { 8 | return -1 9 | } else if nums[(end-start)/2+start] == target { 10 | return (end-start)/2 + start 11 | } 12 | if nums[(end-start)/2+start] < target { 13 | start = (end-start)/2 + start + 1 14 | } else { 15 | end = (end-start)/2 + start - 1 16 | } 17 | } 18 | } 19 | 20 | func removeElement(nums []int, val int) int { 21 | left := 0 22 | right := len(nums) - 1 23 | for left <= right { 24 | for left <= right && nums[left] != val { 25 | left++ 26 | } 27 | for left <= right && nums[right] == val { 28 | right-- 29 | } 30 | if left < right { 31 | nums[left] = nums[right] 32 | left++ 33 | right-- 34 | } 35 | } 36 | return left 37 | } 38 | -------------------------------------------------------------------------------- /day0419/main/search_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestSearch(t *testing.T) { 6 | // Test case 1 7 | nums1 := []int{-1, 0, 3, 5, 9, 12} 8 | target1 := 9 9 | expected1 := 4 10 | result1 := search(nums1, target1) 11 | if result1 != expected1 { 12 | t.Errorf("search(%v, %d) = %d; expected %d", nums1, target1, result1, expected1) 13 | } 14 | 15 | // Test case 2 16 | nums2 := []int{-1, 0, 3, 5, 9, 12} 17 | target2 := 2 18 | expected2 := -1 19 | result2 := search(nums2, target2) 20 | if result2 != expected2 { 21 | t.Errorf("search(%v, %d) = %d; expected %d", nums2, target2, result2, expected2) 22 | } 23 | 24 | // Test case 3 25 | nums3 := []int{1} 26 | target3 := 1 27 | expected3 := 0 28 | result3 := search(nums3, target3) 29 | if result3 != expected3 { 30 | t.Errorf("search(%v, %d) = %d; expected %d", nums3, target3, result3, expected3) 31 | } 32 | 33 | // Test case 4 34 | nums4 := []int{5, 7, 8, 9, 10} 35 | target4 := 6 36 | expected4 := -1 37 | result4 := search(nums4, target4) 38 | if result4 != expected4 { 39 | t.Errorf("search(%v, %d) = %d; expected %d", nums4, target4, result4, expected4) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /day0420/Day2 数组part02.md: -------------------------------------------------------------------------------- 1 | # 数组part02 2 | 3 | ## 977.有序数组的平方 4 | 1. 双指针 5 | ```go 6 | package main 7 | 8 | func sortedSquares(nums []int) []int { 9 | for i := 0; i < len(nums); i++ { 10 | nums[i] = nums[i] * nums[i] 11 | } 12 | res := make([]int, len(nums), len(nums)) 13 | 14 | left, right := 0, len(nums)-1 15 | for i := len(nums) - 1; i >= 0; i-- { 16 | if nums[left] <= nums[right] { 17 | res[i] = nums[right] 18 | right-- 19 | } else { 20 | res[i] = nums[left] 21 | left++ 22 | } 23 | 24 | } 25 | 26 | return res 27 | } 28 | 29 | ``` 30 | 2. 待更新排序解法 31 | 32 | ## 209.长度最小的子数组 33 | 1. 没审题,第一遍写成检测等于target子数组了 34 | ```go 35 | package main 36 | func minSubArrayLen(target int, nums []int) int { 37 | left := 0 38 | sum := 0 39 | res := -1 40 | for i := 0; i < len(nums); i++ { 41 | sum += nums[i] 42 | if sum == target { 43 | if res == -1 || (i-left) < res { 44 | res = i - left 45 | } 46 | } else if sum > target { 47 | for sum > target { 48 | sum -= nums[left] 49 | left++ 50 | } 51 | if sum == target { 52 | if res == -1 || (i-left) < res { 53 | res = i - left 54 | } 55 | } 56 | } 57 | } 58 | return res + 1 59 | } 60 | ``` 61 | 2. 滑动窗口一遍通过 62 | ```go 63 | package main 64 | func minSubArrayLen(target int, nums []int) int { 65 | left := 0 66 | sum := 0 67 | res := -1 68 | for i := 0; i < len(nums); i++ { 69 | sum += nums[i] 70 | if sum >= target { 71 | for sum-nums[left] >= target { 72 | sum -= nums[left] 73 | left++ 74 | } 75 | if res == -1 || (i-left) < res { 76 | res = i - left 77 | } 78 | } 79 | } 80 | return res + 1 81 | } 82 | ``` 83 | 84 | ## 59. 螺旋矩阵 85 | 86 | 1. 模拟法 87 | ```go 88 | package main 89 | import "fmt" 90 | func generateMatrix(n int) [][]int { 91 | /* 92 | ***** 93 | ***** 94 | ***** 95 | ***** 96 | ***** 97 | */ 98 | res := make([][]int, n, n) 99 | for i := 0; i < len(res); i++ { 100 | res[i] = make([]int, n, n) 101 | } 102 | num := 1 103 | x, y := 0, 0 104 | length := n 105 | squ := n * n 106 | for num <= squ { 107 | for i := 0; i < length; i++ { 108 | res[x][y] = num 109 | num++ 110 | y++ 111 | } 112 | if num > squ { 113 | return res 114 | } 115 | y-- 116 | x++ 117 | length-- 118 | for i := 0; i < length; i++ { 119 | res[x][y] = num 120 | num++ 121 | x++ 122 | } 123 | if num > squ { 124 | return res 125 | } 126 | x-- 127 | y-- 128 | for i := 0; i < length; i++ { 129 | res[x][y] = num 130 | num++ 131 | y-- 132 | } 133 | if num > squ { 134 | return res 135 | } 136 | x-- 137 | y++ 138 | length-- 139 | fmt.Println(res) 140 | for i := 0; i < length; i++ { 141 | res[x][y] = num 142 | num++ 143 | x-- 144 | } 145 | if num > squ { 146 | return res 147 | } 148 | x++ 149 | y++ 150 | } 151 | return res 152 | 153 | } 154 | ``` -------------------------------------------------------------------------------- /day0420/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func sortedSquares(nums []int) []int { 6 | for i := 0; i < len(nums); i++ { 7 | nums[i] = nums[i] * nums[i] 8 | } 9 | res := make([]int, len(nums), len(nums)) 10 | 11 | left, right := 0, len(nums)-1 12 | for i := len(nums) - 1; i >= 0; i-- { 13 | if nums[left] <= nums[right] { 14 | res[i] = nums[right] 15 | right-- 16 | } else { 17 | res[i] = nums[left] 18 | left++ 19 | } 20 | 21 | } 22 | 23 | return res 24 | } 25 | 26 | func minSubArrayLen(target int, nums []int) int { 27 | left := 0 28 | sum := 0 29 | res := -1 30 | for i := 0; i < len(nums); i++ { 31 | sum += nums[i] 32 | if sum >= target { 33 | for sum-nums[left] >= target { 34 | sum -= nums[left] 35 | left++ 36 | } 37 | if res == -1 || (i-left) < res { 38 | res = i - left 39 | } 40 | } 41 | } 42 | return res + 1 43 | } 44 | 45 | func generateMatrix(n int) [][]int { 46 | /* 47 | ***** 48 | ***** 49 | ***** 50 | ***** 51 | ***** 52 | */ 53 | res := make([][]int, n, n) 54 | for i := 0; i < len(res); i++ { 55 | res[i] = make([]int, n, n) 56 | } 57 | num := 1 58 | x, y := 0, 0 59 | length := n 60 | squ := n * n 61 | for num <= squ { 62 | for i := 0; i < length; i++ { 63 | res[x][y] = num 64 | num++ 65 | y++ 66 | } 67 | if num > squ { 68 | return res 69 | } 70 | y-- 71 | x++ 72 | length-- 73 | for i := 0; i < length; i++ { 74 | res[x][y] = num 75 | num++ 76 | x++ 77 | } 78 | if num > squ { 79 | return res 80 | } 81 | x-- 82 | y-- 83 | for i := 0; i < length; i++ { 84 | res[x][y] = num 85 | num++ 86 | y-- 87 | } 88 | if num > squ { 89 | return res 90 | } 91 | x-- 92 | y++ 93 | length-- 94 | fmt.Println(res) 95 | for i := 0; i < length; i++ { 96 | res[x][y] = num 97 | num++ 98 | x-- 99 | } 100 | if num > squ { 101 | return res 102 | } 103 | x++ 104 | y++ 105 | } 106 | return res 107 | 108 | } 109 | 110 | type TreeNode struct { 111 | Val int 112 | Left *TreeNode 113 | Right *TreeNode 114 | } 115 | 116 | func dfs(root *TreeNode, num int) int { 117 | if root == nil { 118 | return num 119 | } 120 | num++ 121 | left := dfs(root.Left, num) 122 | right := dfs(root.Right, num) 123 | if right < left { 124 | right = left 125 | } 126 | if num < right { 127 | num = right 128 | } 129 | return num 130 | } 131 | 132 | func maxDepth(root *TreeNode) int { 133 | if root == nil { 134 | return 0 135 | } 136 | num := 1 137 | left := dfs(root.Left, num) 138 | right := dfs(root.Right, num) 139 | if right < left { 140 | right = left 141 | } 142 | if num < right { 143 | num = right 144 | } 145 | return num 146 | } 147 | -------------------------------------------------------------------------------- /day0422/Day4 链表part02.md: -------------------------------------------------------------------------------- 1 | # Day4 链表part2 2 | 3 | ## 24. 两两交换链表中的节点 4 | 1. 使用虚拟头节点加别名命名,真好做~ 5 | ```go 6 | func swapPairs(head *ListNode) *ListNode { 7 | 8 | if head == nil || head.Next == nil { 9 | return head 10 | } 11 | dummyHead := &ListNode{} 12 | dummyHead.Next = head 13 | cur := dummyHead 14 | for cur.Next != nil && cur.Next.Next != nil { 15 | twoNode := cur.Next 16 | threeNode := cur.Next.Next 17 | fourNode := cur.Next.Next.Next 18 | cur.Next = threeNode 19 | threeNode.Next = twoNode 20 | twoNode.Next = fourNode 21 | cur = twoNode 22 | } 23 | return dummyHead.Next 24 | } 25 | 26 | 27 | ``` 28 | ## 19.删除链表的倒数第N个节点 29 | ```go 30 | func removeNthFromEnd(head *ListNode, n int) *ListNode { 31 | dummyHead := new(ListNode) 32 | dummyHead.Next = head 33 | fast := dummyHead 34 | slow := dummyHead 35 | for i := 0; i <= n; i++ { 36 | fast = fast.Next 37 | } 38 | //fast = fast.Next 39 | for fast != nil { 40 | fast = fast.Next 41 | slow = slow.Next 42 | } 43 | slow.Next = slow.Next.Next 44 | return dummyHead.Next 45 | } 46 | ``` 47 | 48 | ## 面试题 02.07. 链表相交 49 | 1. 哈希存储节点 50 | ```go 51 | func getIntersectionNode(headA, headB *ListNode) *ListNode { 52 | nodeMap := make(map[*ListNode]bool) 53 | for headA != nil { 54 | nodeMap[headA] = true 55 | headA = headA.Next 56 | } 57 | for headB != nil { 58 | 59 | if _, ok := nodeMap[headB]; ok { 60 | return headB 61 | } 62 | headB = headB.Next 63 | } 64 | return nil 65 | } 66 | ``` 67 | 2. 双指针 68 | ```go 69 | func getIntersectionNode(headA, headB *ListNode) *ListNode { 70 | curA := headA 71 | curB := headB 72 | for curA != curB { 73 | if curA == nil { 74 | curA = headB 75 | 76 | } else { 77 | curA = curA.Next 78 | } 79 | if curB == nil { 80 | curB = headA 81 | 82 | } else { 83 | curB = curB.Next 84 | } 85 | } 86 | return curA 87 | } 88 | ``` 89 | 90 | ## 142. 环形链表 II 91 | 1. 哈希 92 | ```go 93 | func detectCycle(head *ListNode) *ListNode { 94 | nodeMap := make(map[*ListNode]bool) 95 | 96 | for head != nil { 97 | if _, ok := nodeMap[head]; ok { 98 | return head 99 | } 100 | nodeMap[head] = true 101 | head = head.Next 102 | } 103 | return nil 104 | 105 | } 106 | ``` 107 | 2. 快慢指针 108 | ```go 109 | func detectCycle(head *ListNode) *ListNode { 110 | fast := head 111 | slow := head 112 | if head == nil || head.Next == nil || head.Next.Next == nil { 113 | return nil 114 | } 115 | slow = slow.Next 116 | fast = head.Next.Next 117 | for fast != nil && fast.Next != nil && fast != slow { 118 | fast = fast.Next.Next 119 | slow = slow.Next 120 | 121 | } 122 | if fast == slow { 123 | res := head 124 | for res != slow { 125 | res = res.Next 126 | slow = slow.Next 127 | } 128 | return res 129 | } else { 130 | return nil 131 | } 132 | 133 | } 134 | ``` -------------------------------------------------------------------------------- /day0422/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | . "github.com/halfrost/LeetCode-Go/structures" 6 | ) 7 | 8 | /** 9 | * Definition for singly-linked list. 10 | * type ListNode struct { 11 | * Val int 12 | * Next *ListNode 13 | * } 14 | */ 15 | 16 | func swapPairs(head *ListNode) *ListNode { 17 | 18 | if head == nil || head.Next == nil { 19 | return head 20 | } 21 | dummyHead := &ListNode{} 22 | dummyHead.Next = head 23 | cur := dummyHead 24 | for cur.Next != nil && cur.Next.Next != nil { 25 | twoNode := cur.Next 26 | threeNode := cur.Next.Next 27 | fourNode := cur.Next.Next.Next 28 | cur.Next = threeNode 29 | threeNode.Next = twoNode 30 | twoNode.Next = fourNode 31 | cur = twoNode 32 | } 33 | return dummyHead.Next 34 | } 35 | 36 | /** 37 | * Definition for singly-linked list. 38 | * type ListNode struct { 39 | * Val int 40 | * Next *ListNode 41 | * } 42 | */ 43 | func removeNthFromEnd(head *ListNode, n int) *ListNode { 44 | dummyHead := new(ListNode) 45 | dummyHead.Next = head 46 | fast := dummyHead 47 | slow := dummyHead 48 | for i := 0; i <= n; i++ { 49 | fast = fast.Next 50 | } 51 | //fast = fast.Next 52 | for fast != nil { 53 | fast = fast.Next 54 | slow = slow.Next 55 | } 56 | slow.Next = slow.Next.Next 57 | return dummyHead.Next 58 | } 59 | 60 | /** 61 | * Definition for singly-linked list. 62 | * type ListNode struct { 63 | * Val int 64 | * Next *ListNode 65 | * } 66 | */ 67 | func getIntersectionNode(headA, headB *ListNode) *ListNode { 68 | curA := headA 69 | curB := headB 70 | for curA != curB { 71 | if curA == nil { 72 | curA = headB 73 | 74 | } else { 75 | curA = curA.Next 76 | } 77 | if curB == nil { 78 | curB = headA 79 | 80 | } else { 81 | curB = curB.Next 82 | } 83 | } 84 | return curA 85 | } 86 | 87 | func detectCycle(head *ListNode) *ListNode { 88 | fast := head 89 | slow := head 90 | if head == nil || head.Next == nil || head.Next.Next == nil { 91 | return nil 92 | } 93 | slow = slow.Next 94 | fast = head.Next.Next 95 | for fast != nil && fast.Next != nil && fast != slow { 96 | fast = fast.Next.Next 97 | slow = slow.Next 98 | 99 | } 100 | if fast == slow { 101 | res := head 102 | for res != slow { 103 | res = res.Next 104 | slow = slow.Next 105 | } 106 | return res 107 | } else { 108 | return nil 109 | } 110 | 111 | } 112 | 113 | func main() { 114 | headA := new(ListNode) 115 | headB := new(ListNode) 116 | if headA.Next == headB.Next { 117 | fmt.Println("yes") 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /day0423/Day5.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watoli/Code_Random_Thoughts/657ed431be0f607167792f53decf159c281a787c/day0423/Day5.md -------------------------------------------------------------------------------- /day0424/Day6 哈希表part01.md: -------------------------------------------------------------------------------- 1 | # Day6 哈希表part01 2 | 3 | ## 242. 有效的字母异位词 4 | 1. 哈希表 5 | ```go 6 | func isAnagram(s string, t string) bool { 7 | if len(s) != len(t) { 8 | return false 9 | } 10 | sMap := make(map[byte]int) 11 | for i := 0; i < len(s); i++ { 12 | if _, ok := sMap[s[i]]; !ok { 13 | sMap[s[i]] = 1 14 | } else { 15 | sMap[s[i]]++ 16 | } 17 | } 18 | for i := 0; i < len(t); i++ { 19 | if _, ok := sMap[t[i]]; !ok { 20 | return false 21 | } else { 22 | sMap[t[i]]-- 23 | } 24 | } 25 | for _, v := range sMap { 26 | if v != 0 { 27 | return false 28 | } 29 | } 30 | return true 31 | 32 | } 33 | 34 | ``` 35 | 36 | ## 349. 两个数组的交集 37 | 1. 没多想,哈希表,看答案可以用数组做哈希,挺有意思 38 | ```go 39 | func intersection(nums1 []int, nums2 []int) []int { 40 | numMap := make(map[int]bool) 41 | res := make([]int, 0) 42 | for i := 0; i < len(nums1); i++ { 43 | if _, ok := numMap[nums1[i]]; !ok { 44 | numMap[nums1[i]] = true 45 | } 46 | } 47 | for i := 0; i < len(nums2); i++ { 48 | if v, ok := numMap[nums2[i]]; ok { 49 | if v == true { 50 | res = append(res, nums2[i]) 51 | numMap[nums2[i]] = false 52 | } 53 | } 54 | } 55 | return res 56 | } 57 | ``` 58 | 59 | ## 202. 快乐数 60 | 1. 直接哈希 61 | ```go 62 | func isHappy(n int) bool { 63 | if n == 0 { 64 | return false 65 | } else if n == 1 { 66 | return true 67 | } 68 | happyMap := make(map[int]bool) 69 | for n != 1 { 70 | n = getSum(n) 71 | if _, ok := happyMap[n]; ok { 72 | return false 73 | } 74 | happyMap[n] = true 75 | } 76 | return true 77 | } 78 | ``` 79 | 2. 我应该想到,有环的东西就可以有快慢指针的 80 | ```go 81 | func isHappy(n int) bool { 82 | if n == 1 || getSum(n) == 1 || getSum(getSum(n)) == 1 { 83 | return true 84 | } 85 | fast := getSum(getSum(n)) 86 | slow := getSum(n) 87 | for fast != 1 && fast != slow { 88 | fast = getSum(getSum(fast)) 89 | slow = getSum(slow) 90 | } 91 | return fast == 1 92 | } 93 | ``` 94 | ## 1. 两数之和 95 | 1. 直接哈希 96 | ```go 97 | func twoSum(nums []int, target int) []int { 98 | numMap := make(map[int]int) 99 | for i := 0; i < len(nums); i++ { 100 | if pos, ok := numMap[target-nums[i]]; ok { 101 | return []int{pos, i} 102 | } 103 | if _, ok := numMap[nums[i]]; !ok { 104 | numMap[nums[i]] = i 105 | } 106 | } 107 | return []int{} 108 | } 109 | ``` -------------------------------------------------------------------------------- /day0424/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func isAnagram(s string, t string) bool { 4 | if len(s) != len(t) { 5 | return false 6 | } 7 | sMap := make(map[byte]int) 8 | for i := 0; i < len(s); i++ { 9 | if _, ok := sMap[s[i]]; !ok { 10 | sMap[s[i]] = 1 11 | } else { 12 | sMap[s[i]]++ 13 | } 14 | } 15 | for i := 0; i < len(t); i++ { 16 | if _, ok := sMap[t[i]]; !ok { 17 | return false 18 | } else { 19 | sMap[t[i]]-- 20 | } 21 | } 22 | for _, v := range sMap { 23 | if v != 0 { 24 | return false 25 | } 26 | } 27 | return true 28 | 29 | } 30 | 31 | func intersection(nums1 []int, nums2 []int) []int { 32 | numMap := make(map[int]bool) 33 | res := make([]int, 0) 34 | for i := 0; i < len(nums1); i++ { 35 | if _, ok := numMap[nums1[i]]; !ok { 36 | numMap[nums1[i]] = true 37 | } 38 | } 39 | for i := 0; i < len(nums2); i++ { 40 | if v, ok := numMap[nums2[i]]; ok { 41 | if v == true { 42 | res = append(res, nums2[i]) 43 | numMap[nums2[i]] = false 44 | } 45 | } 46 | } 47 | return res 48 | } 49 | 50 | func getSum(n int) int { 51 | sum := 0 52 | for n != 0 { 53 | sum += (n % 10) * (n % 10) 54 | n /= 10 55 | } 56 | return sum 57 | } 58 | 59 | func isHappy(n int) bool { 60 | if n == 1 || getSum(n) == 1 || getSum(getSum(n)) == 1 { 61 | return true 62 | } 63 | fast := getSum(getSum(n)) 64 | slow := getSum(n) 65 | for fast != 1 && fast != slow { 66 | fast = getSum(getSum(fast)) 67 | slow = getSum(slow) 68 | } 69 | return fast == 1 70 | } 71 | 72 | func twoSum(nums []int, target int) []int { 73 | numMap := make(map[int]int) 74 | for i := 0; i < len(nums); i++ { 75 | if pos, ok := numMap[target-nums[i]]; ok { 76 | return []int{pos, i} 77 | } 78 | if _, ok := numMap[nums[i]]; !ok { 79 | numMap[nums[i]] = i 80 | } 81 | } 82 | return []int{} 83 | } 84 | -------------------------------------------------------------------------------- /day0425/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sort" 5 | ) 6 | 7 | func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) (res int) { 8 | mapAB := make(map[int]int) 9 | for i := 0; i < len(nums1); i++ { 10 | for j := 0; j < len(nums2); j++ { 11 | if _, ok := mapAB[nums1[i]+nums2[j]]; ok { 12 | mapAB[nums1[i]+nums2[j]]++ 13 | } else { 14 | mapAB[nums1[i]+nums2[j]] = 1 15 | } 16 | } 17 | } 18 | for i := 0; i < len(nums3); i++ { 19 | for j := 0; j < len(nums4); j++ { 20 | if _, ok := mapAB[-nums3[i]-nums4[j]]; ok { 21 | res += mapAB[-nums3[i]-nums4[j]] 22 | } 23 | } 24 | } 25 | return 26 | } 27 | 28 | func canConstruct(ransomNote string, magazine string) bool { 29 | mapMag := make(map[byte]int) 30 | for i := 0; i < len(magazine); i++ { 31 | if _, ok := mapMag[magazine[i]]; !ok { 32 | mapMag[magazine[i]] = 1 33 | } else { 34 | mapMag[magazine[i]]++ 35 | } 36 | } 37 | for i := 0; i < len(ransomNote); i++ { 38 | if _, ok := mapMag[ransomNote[i]]; !ok { 39 | return false 40 | } 41 | if mapMag[ransomNote[i]] == 0 { 42 | return false 43 | } 44 | mapMag[ransomNote[i]]-- 45 | } 46 | return true 47 | } 48 | 49 | func threeSum(nums []int) [][]int { 50 | sort.Ints(nums) 51 | left := 0 52 | right := len(nums) - 1 53 | res := make([][]int, 0) 54 | 55 | for i := 0; i < len(nums)-1; i++ { 56 | if nums[i] > 0 { 57 | continue 58 | } 59 | if i > 0 && nums[i] == nums[i-1] { 60 | continue 61 | } 62 | left = i + 1 63 | right = len(nums) - 1 64 | for left < right { 65 | if nums[left]+nums[right] == -nums[i] { 66 | res = append(res, []int{nums[i], nums[left], nums[right]}) 67 | left++ 68 | for left < right && nums[left] == nums[left-1] { 69 | left++ 70 | } 71 | right-- 72 | for left < right && nums[right] == nums[right+1] { 73 | right-- 74 | } 75 | } else if nums[left]+nums[right] > -nums[i] { 76 | right-- 77 | 78 | } else { 79 | left++ 80 | 81 | } 82 | } 83 | } 84 | return res 85 | } 86 | 87 | func fourSum(nums []int, target int) [][]int { 88 | sort.Ints(nums) 89 | left := 0 90 | right := len(nums) - 1 91 | res := make([][]int, 0) 92 | for i := 0; i < len(nums); i++ { 93 | if target > 0 && nums[i] > target { 94 | continue 95 | } 96 | if i > 0 && nums[i] == nums[i-1] { 97 | continue 98 | } 99 | for j := i + 1; j < len(nums); j++ { 100 | if target > 0 && nums[j] > target-nums[i] { 101 | continue 102 | } 103 | if j > i+1 && nums[j] == nums[j-1] { 104 | continue 105 | } 106 | 107 | left = j + 1 108 | right = len(nums) - 1 109 | for left < right { 110 | if nums[left]+nums[right] == target-nums[i]-nums[j] { 111 | res = append(res, []int{nums[i], nums[j], nums[left], nums[right]}) 112 | left++ 113 | for left < right && nums[left] == nums[left-1] { 114 | left++ 115 | } 116 | right-- 117 | for left < right && nums[right] == nums[right+1] { 118 | right-- 119 | } 120 | } else if nums[i]+nums[j]+nums[left]+nums[right] > target { 121 | right-- 122 | 123 | } else { 124 | left++ 125 | 126 | } 127 | } 128 | 129 | } 130 | } 131 | return res 132 | } 133 | -------------------------------------------------------------------------------- /day0426/Day8 字符串part01.md: -------------------------------------------------------------------------------- 1 | # Day8字符串part01 2 | 3 | ## 344. 反转字符串 4 | 1. 直接反转 5 | ```go 6 | func reverseString(s []byte) { 7 | lenS := len(s) 8 | for i := 0; i < lenS/2; i++ { 9 | s[i], s[lenS-1-i] = s[lenS-1-i], s[i] 10 | } 11 | } 12 | ``` 13 | 14 | ## 541. 反转字符串 II 15 | 2. 还是直接反转,其中遍历是i+=2*k能够极大缩短时间,注意技巧 16 | ```go 17 | func reverseStr(s string, k int) string { 18 | resByte := []byte(s) 19 | 20 | for i := 0; i < len(s); i = i + 2*k { 21 | 22 | if i+k <= len(s) { 23 | reverseString(resByte[i : i+k]) 24 | } else if i+k > len(s) { 25 | reverseString(resByte[i:]) 26 | } 27 | } 28 | return string(resByte) 29 | } 30 | ``` 31 | 32 | ## 剑指 Offer 05. 替换空格 33 | 1. 添加元素,空间复杂度为O(n) 34 | ```go 35 | func replaceSpace(s string) (res string) { 36 | for i := 0; i < len(s); i++ { 37 | if s[i] == ' ' { 38 | res += "%20" 39 | } else { 40 | res += fmt.Sprintf("%c", s[i]) 41 | } 42 | } 43 | return 44 | } 45 | ``` 46 | 2. 双指针法 47 | ```go 48 | func replaceSpace(s string) string { 49 | nSpace := 0 50 | for i := 0; i < len(s); i++ { 51 | if s[i] == ' ' { 52 | nSpace++ 53 | } 54 | } 55 | res := make([]byte, nSpace*2) 56 | res = append([]byte(s), res...) 57 | fast := len(s) - 1 58 | slow := len(res) - 1 59 | for fast >= 0 { 60 | if s[fast] == ' ' { 61 | res[slow] = '0' 62 | res[slow-1] = '2' 63 | res[slow-2] = '%' 64 | slow -= 3 65 | fast-- 66 | } else { 67 | res[slow] = s[fast] 68 | slow-- 69 | fast-- 70 | } 71 | } 72 | return fmt.Sprintf("%s", res) 73 | } 74 | ``` 75 | 76 | ## 151. 反转字符串中的单词 77 | 1. 和反转字符串思路类似,需要优化删除空格的算法 78 | ```go 79 | func reverseWords(s string) string { 80 | sliceS := make([][]byte, 0) 81 | tmpS := make([]byte, 0) 82 | for i := 0; i < len(s); i++ { 83 | if s[i] != ' ' { 84 | tmpS = append(tmpS, s[i]) 85 | } else { 86 | if len(tmpS) != 0 { 87 | sliceS = append(sliceS, tmpS) 88 | } 89 | tmpS = []byte{} 90 | } 91 | } 92 | if len(tmpS) != 0 { 93 | sliceS = append(sliceS, tmpS) 94 | } 95 | for i := 0; i < len(sliceS)/2; i++ { 96 | sliceS[i], sliceS[len(sliceS)-1-i] = sliceS[len(sliceS)-1-i], sliceS[i] 97 | } 98 | res := fmt.Sprintf("%s", sliceS[0]) 99 | for i := 1; i < len(sliceS); i++ { 100 | if len(sliceS[i]) != 0 { 101 | res += " " + fmt.Sprintf("%s", sliceS[i]) 102 | } 103 | } 104 | return res 105 | } 106 | ``` 107 | 108 | ## 剑指 Offer 58 - II. 左旋转字符串 109 | 1. 字符串拼接 110 | ```go 111 | func reverseLeftWords(s string, n int) string { 112 | res := make([]byte, len(s)) 113 | lenS := len(s) 114 | for i := 0; i < n; i++ { 115 | res[lenS-n+i] = s[i] 116 | } 117 | for i := n; i < lenS; i++ { 118 | res[i-n] = s[i] 119 | } 120 | return fmt.Sprintf("%s", res) 121 | } 122 | ``` 123 | 2. 左旋 124 | ```go 125 | func reverseLeftWords(s string, n int) string { 126 | res := []byte(s) 127 | reverseString(res[:n]) 128 | reverseString(res[n:]) 129 | reverseString(res) 130 | return fmt.Sprintf("%s", res) 131 | } 132 | ``` -------------------------------------------------------------------------------- /day0426/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func reverseString(s []byte) { 8 | lenS := len(s) 9 | for i := 0; i < lenS/2; i++ { 10 | s[i], s[lenS-1-i] = s[lenS-1-i], s[i] 11 | } 12 | } 13 | 14 | func reverseStr(s string, k int) string { 15 | resByte := []byte(s) 16 | 17 | for i := 0; i < len(s); i = i + 2*k { 18 | 19 | if i+k <= len(s) { 20 | reverseString(resByte[i : i+k]) 21 | } else if i+k > len(s) { 22 | reverseString(resByte[i:]) 23 | } 24 | } 25 | return string(resByte) 26 | } 27 | 28 | func replaceSpace(s string) string { 29 | nSpace := 0 30 | for i := 0; i < len(s); i++ { 31 | if s[i] == ' ' { 32 | nSpace++ 33 | } 34 | } 35 | res := make([]byte, nSpace*2) 36 | res = append([]byte(s), res...) 37 | fast := len(s) - 1 38 | slow := len(res) - 1 39 | for fast >= 0 { 40 | if s[fast] == ' ' { 41 | res[slow] = '0' 42 | res[slow-1] = '2' 43 | res[slow-2] = '%' 44 | slow -= 3 45 | fast-- 46 | } else { 47 | res[slow] = s[fast] 48 | slow-- 49 | fast-- 50 | } 51 | } 52 | return fmt.Sprintf("%s", res) 53 | } 54 | 55 | func reverseWords(s string) string { 56 | sliceS := make([][]byte, 0) 57 | tmpS := make([]byte, 0) 58 | for i := 0; i < len(s); i++ { 59 | if s[i] != ' ' { 60 | tmpS = append(tmpS, s[i]) 61 | } else { 62 | if len(tmpS) != 0 { 63 | sliceS = append(sliceS, tmpS) 64 | } 65 | tmpS = []byte{} 66 | } 67 | } 68 | if len(tmpS) != 0 { 69 | sliceS = append(sliceS, tmpS) 70 | } 71 | for i := 0; i < len(sliceS)/2; i++ { 72 | sliceS[i], sliceS[len(sliceS)-1-i] = sliceS[len(sliceS)-1-i], sliceS[i] 73 | } 74 | res := fmt.Sprintf("%s", sliceS[0]) 75 | for i := 1; i < len(sliceS); i++ { 76 | if len(sliceS[i]) != 0 { 77 | res += " " + fmt.Sprintf("%s", sliceS[i]) 78 | } 79 | } 80 | return res 81 | } 82 | 83 | func reverseLeftWords(s string, n int) string { 84 | res := []byte(s) 85 | reverseString(res[:n]) 86 | reverseString(res[n:]) 87 | reverseString(res) 88 | return fmt.Sprintf("%s", res) 89 | } 90 | -------------------------------------------------------------------------------- /day0427/Day9 字符串part02.md: -------------------------------------------------------------------------------- 1 | # Day9字符串part02 2 | ## 28. 找出字符串中第一个匹配项的下标 3 | 1. 滑动窗口 4 | ```go 5 | func strStr(haystack string, needle string) int { 6 | if len(haystack) < len(needle) { 7 | return -1 8 | } 9 | lenN := len(needle) 10 | lenH := len(haystack) 11 | slow := 0 12 | fast := lenN - 1 13 | for fast != lenH { 14 | if haystack[fast] == needle[lenN-1] { 15 | isNeedle := true 16 | for i := 0; i < lenN; i++ { 17 | if haystack[slow+i] != needle[i] { 18 | isNeedle = false 19 | } 20 | } 21 | if isNeedle == true { 22 | return slow 23 | } 24 | } 25 | fast++ 26 | slow++ 27 | } 28 | return -1 29 | } 30 | ``` 31 | 2. KMP 32 | ```go 33 | func getNext(next []int, s string) { 34 | j := 0 35 | next[0] = j 36 | for i := 1; i < len(s); i++ { 37 | for j > 0 && s[i] != s[j] { 38 | j = next[j-1] 39 | } 40 | if s[i] == s[j] { 41 | j++ 42 | } 43 | next[i] = j 44 | } 45 | } 46 | 47 | func strStr(haystack string, needle string) int { 48 | if len(haystack) < len(needle) { 49 | return -1 50 | } else if len(needle) == 0 { 51 | return 0 52 | } 53 | next := make([]int, len(needle)) 54 | getNext(next, needle) 55 | j := 0 56 | for i := 0; i < len(haystack); i++ { 57 | for j > 0 && haystack[i] != needle[j] { 58 | j = next[j-1] 59 | } 60 | if haystack[i] == needle[j] { 61 | j++ 62 | } 63 | if j == len(needle) { 64 | return i - len(needle) + 1 65 | } 66 | } 67 | return -1 68 | } 69 | ``` 70 | 71 | ## 459. 重复的子字符串 72 | 1. 字符串匹配 73 | ```go 74 | func repeatedSubstringPattern(s string) bool { 75 | if len(s) == 1 { 76 | return false 77 | } 78 | fast := 1 79 | lenS := len(s) 80 | i := 0 81 | for i < len(s) { 82 | fmt.Println(fast) 83 | isSub := true 84 | for j := 0; j < fast; j++ { 85 | if s[i+j] != s[j] { 86 | isSub = false 87 | } 88 | } 89 | if isSub == false { 90 | if i > lenS/2 { 91 | return false 92 | } 93 | for k := 1; fast+k < lenS; k++ { 94 | if fast+k > lenS/2 { 95 | return false 96 | } 97 | if s[fast+k] == s[0] && lenS%(fast+k) == 0 { 98 | fast += k 99 | i = 0 100 | break 101 | } 102 | } 103 | 104 | } 105 | i += fast 106 | if i == lenS && isSub == true { 107 | return true 108 | } 109 | } 110 | return false 111 | } 112 | ``` 113 | 114 | 2. KMP 115 | ```go 116 | func repeatedSubstringPattern(s string) bool { 117 | if len(s) == 1 || len(s) == 0 { 118 | return false 119 | } 120 | j := 0 121 | lenS := len(s) 122 | next := make([]int, lenS) 123 | next[0] = j 124 | for i := 1; i < lenS; i++ { 125 | for j > 0 && s[j] != s[i] { 126 | j = next[j-1] 127 | } 128 | if s[j] == s[i] { 129 | j++ 130 | } 131 | next[i] = j 132 | } 133 | if next[lenS-1] > 0 && lenS%(lenS-next[lenS-1]) == 0 { 134 | return true 135 | } 136 | return false 137 | 138 | } 139 | 140 | ``` -------------------------------------------------------------------------------- /day0427/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func getNext(next []int, s string) { 4 | j := 0 5 | next[0] = j 6 | for i := 1; i < len(s); i++ { 7 | for j > 0 && s[i] != s[j] { 8 | j = next[j-1] 9 | } 10 | if s[i] == s[j] { 11 | j++ 12 | } 13 | next[i] = j 14 | } 15 | } 16 | 17 | func strStr(haystack string, needle string) int { 18 | if len(haystack) < len(needle) { 19 | return -1 20 | } else if len(needle) == 0 { 21 | return 0 22 | } 23 | next := make([]int, len(needle)) 24 | getNext(next, needle) 25 | j := 0 26 | for i := 0; i < len(haystack); i++ { 27 | for j > 0 && haystack[i] != needle[j] { 28 | j = next[j-1] 29 | } 30 | if haystack[i] == needle[j] { 31 | j++ 32 | } 33 | if j == len(needle) { 34 | return i - len(needle) + 1 35 | } 36 | } 37 | return -1 38 | } 39 | 40 | func repeatedSubstringPattern(s string) bool { 41 | if len(s) == 1 || len(s) == 0 { 42 | return false 43 | } 44 | j := 0 45 | lenS := len(s) 46 | next := make([]int, lenS) 47 | next[0] = j 48 | for i := 1; i < lenS; i++ { 49 | for j > 0 && s[j] != s[i] { 50 | j = next[j-1] 51 | } 52 | if s[j] == s[i] { 53 | j++ 54 | } 55 | next[i] = j 56 | } 57 | if next[lenS-1] > 0 && lenS%(lenS-next[lenS-1]) == 0 { 58 | return true 59 | } 60 | return false 61 | 62 | } 63 | -------------------------------------------------------------------------------- /day0428/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Queue struct { 4 | data []int 5 | len int 6 | } 7 | 8 | func NewQueue() *Queue { 9 | return &Queue{ 10 | data: []int{}, 11 | len: 0, 12 | } 13 | } 14 | 15 | func (q *Queue) Push(num int) { 16 | q.data = append(q.data, num) 17 | q.len++ 18 | } 19 | 20 | func (q *Queue) Pop() int { 21 | res := q.data[0] 22 | q.data = q.data[1:] 23 | q.len-- 24 | return res 25 | } 26 | 27 | func (q *Queue) Peek() int { 28 | return q.data[0] 29 | } 30 | 31 | func (q *Queue) Size() int { 32 | return q.len 33 | } 34 | 35 | func (q *Queue) Empty() bool { 36 | if q.len == 0 { 37 | return true 38 | } else { 39 | return false 40 | } 41 | } 42 | 43 | type Stack struct { 44 | data []int 45 | len int 46 | } 47 | 48 | func NewStack() *Stack { 49 | return &Stack{ 50 | data: []int{}, 51 | len: 0, 52 | } 53 | } 54 | 55 | func (s *Stack) Push(num int) { 56 | s.data = append(s.data, num) 57 | s.len++ 58 | } 59 | 60 | func (s *Stack) Pop() int { 61 | res := s.data[s.len-1] 62 | s.data = s.data[:s.len-1] 63 | s.len-- 64 | return res 65 | } 66 | 67 | func (s *Stack) Peek() int { 68 | return s.data[s.len-1] 69 | } 70 | 71 | func (s *Stack) Size() int { 72 | return s.len 73 | } 74 | func (s *Stack) Empty() bool { 75 | if s.len == 0 { 76 | return true 77 | } else { 78 | return false 79 | } 80 | } 81 | 82 | type MyQueue struct { 83 | inStack Stack 84 | outStack Stack 85 | } 86 | 87 | func ConstructorStack() MyQueue { 88 | inS := *NewStack() 89 | outS := *NewStack() 90 | return MyQueue{inStack: inS, outStack: outS} 91 | } 92 | 93 | func (q *MyQueue) Push(x int) { 94 | q.inStack.Push(x) 95 | } 96 | 97 | func (q *MyQueue) Pop() int { 98 | if q.outStack.Empty() { 99 | for !q.inStack.Empty() { 100 | q.outStack.Push(q.inStack.Pop()) 101 | } 102 | } 103 | return q.outStack.Pop() 104 | } 105 | 106 | func (q *MyQueue) Peek() int { 107 | if q.outStack.Empty() { 108 | for !q.inStack.Empty() { 109 | q.outStack.Push(q.inStack.Pop()) 110 | } 111 | } 112 | return q.outStack.Peek() 113 | } 114 | 115 | func (q *MyQueue) Empty() bool { 116 | return q.outStack.Empty() && q.inStack.Empty() 117 | } 118 | 119 | /** 120 | * Your MyQueue object will be instantiated and called as such: 121 | * obj := Constructor(); 122 | * obj.Push(x); 123 | * param_2 := obj.Pop(); 124 | * param_3 := obj.Peek(); 125 | * param_4 := obj.Empty(); 126 | */ 127 | 128 | type MyStack struct { 129 | cycle Queue 130 | } 131 | 132 | func Constructor() MyStack { 133 | Cq := *NewQueue() 134 | return MyStack{cycle: Cq} 135 | } 136 | 137 | func (s *MyStack) Push(x int) { 138 | s.cycle.Push(x) 139 | } 140 | 141 | func (s *MyStack) Pop() int { 142 | for i := 0; i < s.cycle.len-1; i++ { 143 | s.cycle.Push(s.cycle.Pop()) 144 | } 145 | return s.cycle.Pop() 146 | } 147 | 148 | func (s *MyStack) Top() int { 149 | for i := 0; i < s.cycle.len-1; i++ { 150 | s.cycle.Push(s.cycle.Pop()) 151 | } 152 | res := s.cycle.Peek() 153 | s.cycle.Push(s.cycle.Pop()) 154 | return res 155 | } 156 | 157 | func (s *MyStack) Empty() bool { 158 | return s.cycle.Empty() 159 | } 160 | 161 | /** 162 | * Your MyStack object will be instantiated and called as such: 163 | * obj := Constructor(); 164 | * obj.Push(x); 165 | * param_2 := obj.Pop(); 166 | * param_3 := obj.Top(); 167 | * param_4 := obj.Empty(); 168 | */ 169 | -------------------------------------------------------------------------------- /day0429/Day11 栈与队列part02.md: -------------------------------------------------------------------------------- 1 | # Day11 栈与队列part02 2 | 3 | # 20. 有效的括号 4 | 1. 栈 5 | ```go 6 | func isValid(s string) bool { 7 | 8 | bracketMap := map[byte]int{ 9 | '(': 0, ')': 1, 10 | '{': 0, '}': 1, 11 | '[': 0, ']': 1, 12 | } 13 | bracketMatch := map[byte]byte{ 14 | '(': ')', 15 | '{': '}', 16 | '[': ']', 17 | } 18 | bracketStack := NewStack() 19 | for i := 0; i < len(s); i++ { 20 | //fmt.Println(bracketStack.data) 21 | //fmt.Println(s[i]) 22 | v, ok := bracketMap[s[i]] 23 | if ok { 24 | if v == 0 { 25 | bracketStack.Push(s[i]) 26 | } else if v == 1 { 27 | if bracketStack.Empty() { 28 | return false 29 | } 30 | if m, _ := bracketMatch[bracketStack.Pop().(byte)]; m != s[i] { 31 | return false 32 | } 33 | } 34 | } 35 | } 36 | if bracketStack.Empty() { 37 | return true 38 | } else { 39 | return false 40 | } 41 | } 42 | ``` 43 | 44 | # 1047. 删除字符串中的所有相邻重复项 45 | 1. 栈实现 46 | ```go 47 | func removeDuplicates(s string) string { 48 | resS := NewStack() 49 | for i := 0; i < len(s); i++ { 50 | if (!resS.Empty()) && resS.Peek() == s[i] { 51 | resS.Pop() 52 | } else { 53 | resS.Push(s[i]) 54 | } 55 | } 56 | //fmt.Println(resS.data) 57 | lenS := resS.Size() 58 | res := make([]byte, lenS) 59 | for i := 0; i < lenS; i++ { 60 | res[lenS-1-i] = resS.Pop().(byte) 61 | } 62 | return fmt.Sprintf("%s", res) 63 | } 64 | ``` 65 | 66 | # 150. 逆波兰表达式求值 67 | 1. 栈实现 68 | ```go 69 | func evalRPN(tokens []string) int { 70 | operatorMap := map[string]func(x, y int) int{ 71 | "+": func(x, y int) int { 72 | return x + y 73 | }, 74 | "-": func(x, y int) int { 75 | return y-x 76 | }, 77 | "*": func(x, y int) int { 78 | return x * y 79 | }, 80 | "/": func(x, y int) int { 81 | return y / x 82 | }, 83 | } 84 | resS := NewStack() 85 | for i := 0; i < len(tokens); i++ { 86 | funcOper, ok := operatorMap[tokens[i]] 87 | if !ok { 88 | atoi, err := strconv.Atoi(tokens[i]) 89 | if err != nil { 90 | return -1 91 | } 92 | resS.Push(atoi) 93 | } else { 94 | resS.Push(funcOper(resS.Pop().(int), resS.Pop().(int))) 95 | } 96 | } 97 | return resS.Pop().(int) 98 | 99 | } 100 | ``` -------------------------------------------------------------------------------- /day0429/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type T interface { 9 | } 10 | 11 | type Stack struct { 12 | data []T 13 | len int 14 | } 15 | 16 | func NewStack() *Stack { 17 | return &Stack{ 18 | data: []T{}, 19 | len: 0, 20 | } 21 | } 22 | 23 | func (s *Stack) Push(c T) { 24 | s.data = append(s.data, c) 25 | s.len++ 26 | } 27 | 28 | func (s *Stack) Pop() T { 29 | res := s.data[s.len-1] 30 | s.data = s.data[:s.len-1] 31 | s.len-- 32 | return res 33 | } 34 | 35 | func (s *Stack) Peek() T { 36 | return s.data[s.len-1] 37 | } 38 | 39 | func (s *Stack) Size() int { 40 | return s.len 41 | } 42 | func (s *Stack) Empty() bool { 43 | if s.len == 0 { 44 | return true 45 | } else { 46 | return false 47 | } 48 | } 49 | 50 | func isValid(s string) bool { 51 | 52 | bracketMap := map[byte]int{ 53 | '(': 0, ')': 1, 54 | '{': 0, '}': 1, 55 | '[': 0, ']': 1, 56 | } 57 | bracketMatch := map[byte]byte{ 58 | '(': ')', 59 | '{': '}', 60 | '[': ']', 61 | } 62 | bracketStack := NewStack() 63 | for i := 0; i < len(s); i++ { 64 | //fmt.Println(bracketStack.data) 65 | //fmt.Println(s[i]) 66 | v, ok := bracketMap[s[i]] 67 | if ok { 68 | if v == 0 { 69 | bracketStack.Push(s[i]) 70 | } else if v == 1 { 71 | if bracketStack.Empty() { 72 | return false 73 | } 74 | if m, _ := bracketMatch[bracketStack.Pop().(byte)]; m != s[i] { 75 | return false 76 | } 77 | } 78 | } 79 | } 80 | if bracketStack.Empty() { 81 | return true 82 | } else { 83 | return false 84 | } 85 | } 86 | 87 | func removeDuplicates(s string) string { 88 | resS := NewStack() 89 | for i := 0; i < len(s); i++ { 90 | if (!resS.Empty()) && resS.Peek() == s[i] { 91 | resS.Pop() 92 | } else { 93 | resS.Push(s[i]) 94 | } 95 | } 96 | //fmt.Println(resS.data) 97 | lenS := resS.Size() 98 | res := make([]byte, lenS) 99 | for i := 0; i < lenS; i++ { 100 | res[lenS-1-i] = resS.Pop().(byte) 101 | } 102 | return fmt.Sprintf("%s", res) 103 | } 104 | 105 | func evalRPN(tokens []string) int { 106 | operatorMap := map[string]func(x, y int) int{ 107 | "+": func(x, y int) int { 108 | return x + y 109 | }, 110 | "-": func(x, y int) int { 111 | return y - x 112 | }, 113 | "*": func(x, y int) int { 114 | return x * y 115 | }, 116 | "/": func(x, y int) int { 117 | return y / x 118 | }, 119 | } 120 | resS := NewStack() 121 | for i := 0; i < len(tokens); i++ { 122 | funcOper, ok := operatorMap[tokens[i]] 123 | if !ok { 124 | atoi, err := strconv.Atoi(tokens[i]) 125 | if err != nil { 126 | return -1 127 | } 128 | resS.Push(atoi) 129 | } else { 130 | resS.Push(funcOper(resS.Pop().(int), resS.Pop().(int))) 131 | } 132 | } 133 | return resS.Pop().(int) 134 | 135 | } 136 | -------------------------------------------------------------------------------- /day0501/Day13 栈与队列part03.md: -------------------------------------------------------------------------------- 1 | # Day13 栈与队列part03 2 | 3 | # 239. 滑动窗口最大值 4 | 1. 单调队列,这里面push的大于号,真tm的关键! 5 | ```go 6 | type MonotonicQueue struct { 7 | queue []int 8 | len int 9 | } 10 | 11 | func NewMonotonicQueue() *MonotonicQueue { 12 | NewQueue := make([]int, 0) 13 | return &MonotonicQueue{queue: NewQueue, len: 0} 14 | } 15 | 16 | func (q *MonotonicQueue) Push(x int) { 17 | for q.len != 0 && q.queue[q.len-1] < x { 18 | q.queue = q.queue[:q.len-1] 19 | q.len-- 20 | } 21 | q.queue = append(q.queue, x) 22 | q.len++ 23 | } 24 | 25 | func (q *MonotonicQueue) Pop() { 26 | q.queue = q.queue[1:] 27 | q.len-- 28 | } 29 | 30 | func (q MonotonicQueue) Peek() int { 31 | return q.queue[0] 32 | } 33 | func (q MonotonicQueue) Size() int { 34 | return len(q.queue) 35 | } 36 | 37 | func maxSlidingWindow(nums []int, k int) []int { 38 | lenN := len(nums) 39 | res := make([]int, lenN-k+1) 40 | MoQ := NewMonotonicQueue() 41 | for i := 0; i < k; i++ { 42 | MoQ.Push(nums[i]) 43 | } 44 | res[0] = MoQ.Peek() 45 | for i := k; i < lenN; i++ { 46 | if MoQ.Size() > 0 && MoQ.Peek() == nums[i-k] { 47 | MoQ.Pop() 48 | } 49 | MoQ.Push(nums[i]) 50 | res[i-k+1] = MoQ.Peek() 51 | } 52 | return res 53 | } 54 | func main() { 55 | var a []int 56 | b := make([]int, 0) 57 | c := []int{} 58 | 59 | fmt.Println(a, b, c) 60 | } 61 | 62 | ``` 63 | 64 | ## 347. 前 K 个高频元素 65 | 1. 最小堆实现 66 | ```go 67 | type MinHeap []int 68 | 69 | func (h MinHeap) Len() int { 70 | return len(h) 71 | } 72 | 73 | func (h MinHeap) Less(x, y int) bool { 74 | return h[x] < h[y] 75 | } 76 | 77 | func (h MinHeap) Swap(x, y int) { 78 | (h)[x], (h)[y] = (h)[y], (h)[x] 79 | } 80 | 81 | func (h *MinHeap) Push(x interface{}) { 82 | *h = append(*h, x.(int)) 83 | } 84 | 85 | func (h *MinHeap) Pop() interface{} { 86 | lenH := len(*h) 87 | res := (*h)[lenH-1] 88 | *h = (*h)[:lenH-1] 89 | return res 90 | } 91 | 92 | func topKFrequent(nums []int, k int) []int { 93 | numMap := map[int]int{} 94 | for i := 0; i < len(nums); i++ { 95 | if _, ok := numMap[nums[i]]; !ok { 96 | numMap[nums[i]] = 1 97 | } else { 98 | numMap[nums[i]]++ 99 | } 100 | } 101 | res := &MinHeap{} 102 | heap.Init(res) 103 | for _, v := range numMap { 104 | if len(*res) < k { 105 | heap.Push(res, v) 106 | } else { 107 | if v > (*res)[0] { 108 | heap.Pop(res) 109 | heap.Push(res, v) 110 | } 111 | } 112 | } 113 | 114 | min := (*res)[0] 115 | i := 0 116 | for key, v := range numMap { 117 | if v >= min { 118 | (*res)[i] = key 119 | i++ 120 | } 121 | if i >= k { 122 | break 123 | } 124 | } 125 | return *res 126 | } 127 | ``` -------------------------------------------------------------------------------- /day0503/Day15二叉树part02.md: -------------------------------------------------------------------------------- 1 | # Day15 二叉树part2 2 | ## 层序遍历 3 | 1. 迭代 4 | ```go 5 | func levelOrder(root *TreeNode) [][]int { 6 | res := make([][]int, 0) 7 | if root == nil { 8 | return res 9 | } 10 | var tmpRes []int 11 | nodeStack := []*TreeNode{root} 12 | var tmpNode *TreeNode 13 | for len(nodeStack) != 0 { 14 | lenS := len(nodeStack) 15 | tmpRes = []int{} 16 | for i := 0; i < lenS; i++ { 17 | tmpNode = nodeStack[0] 18 | nodeStack = nodeStack[1:] 19 | tmpRes = append(tmpRes, tmpNode.Val) 20 | if tmpNode.Left != nil { 21 | nodeStack = append(nodeStack, tmpNode.Left) 22 | } 23 | if tmpNode.Right != nil { 24 | nodeStack = append(nodeStack, tmpNode.Right) 25 | } 26 | } 27 | res = append(res, tmpRes) 28 | } 29 | return res 30 | } 31 | ``` 32 | 33 | ## 226.翻转二叉树 34 | 1. 递归 35 | ```go 36 | func invertTree(root *TreeNode) *TreeNode { 37 | if root == nil { 38 | return root 39 | } 40 | root.Left, root.Right = root.Right, root.Left 41 | invertTree(root.Left) 42 | invertTree(root.Right) 43 | return root 44 | } 45 | ``` 46 | 47 | ## 101. 对称二叉树 48 | 1. 迭代 49 | ```go 50 | func isSymmetric(root *TreeNode) bool { 51 | if root == nil { 52 | return true 53 | } 54 | lenS := 0 55 | nodeStack := []*TreeNode{root.Left, root.Right} 56 | for len(nodeStack) != 0 { 57 | var tmpStack []*TreeNode 58 | lenS = len(nodeStack) 59 | for i := 0; i < lenS/2; i++ { 60 | if nodeStack[i] == nil || nodeStack[lenS-1-i] == nil { 61 | if nodeStack[i] == nil && nodeStack[lenS-1-i] == nil { 62 | continue 63 | } 64 | return false 65 | } else if nodeStack[i].Val == nodeStack[lenS-1-i].Val { 66 | tmpStack = append([]*TreeNode{nodeStack[i].Left, nodeStack[i].Right}, tmpStack...) 67 | tmpStack = append(tmpStack, nodeStack[lenS-1-i].Left, nodeStack[lenS-1-i].Right) 68 | } else { 69 | return false 70 | } 71 | } 72 | nodeStack = tmpStack 73 | } 74 | return true 75 | } 76 | ``` -------------------------------------------------------------------------------- /day0503/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | "fmt" 6 | "reflect" 7 | "runtime" 8 | "unsafe" 9 | ) 10 | 11 | func levelOrder(root *TreeNode) [][]int { 12 | res := make([][]int, 0) 13 | if root == nil { 14 | return res 15 | } 16 | var tmpRes []int 17 | nodeStack := []*TreeNode{root} 18 | var tmpNode *TreeNode 19 | for len(nodeStack) != 0 { 20 | lenS := len(nodeStack) 21 | tmpRes = []int{} 22 | for i := 0; i < lenS; i++ { 23 | tmpNode = nodeStack[0] 24 | nodeStack = nodeStack[1:] 25 | tmpRes = append(tmpRes, tmpNode.Val) 26 | if tmpNode.Left != nil { 27 | nodeStack = append(nodeStack, tmpNode.Left) 28 | } 29 | if tmpNode.Right != nil { 30 | nodeStack = append(nodeStack, tmpNode.Right) 31 | } 32 | } 33 | res = append(res, tmpRes) 34 | } 35 | return res 36 | } 37 | 38 | func invertTree(root *TreeNode) *TreeNode { 39 | if root == nil { 40 | return root 41 | } 42 | root.Left, root.Right = root.Right, root.Left 43 | invertTree(root.Left) 44 | invertTree(root.Right) 45 | return root 46 | } 47 | 48 | func isSymmetric(root *TreeNode) bool { 49 | if root == nil { 50 | return true 51 | } 52 | lenS := 0 53 | nodeStack := []*TreeNode{root.Left, root.Right} 54 | for len(nodeStack) != 0 { 55 | var tmpStack []*TreeNode 56 | lenS = len(nodeStack) 57 | for i := 0; i < lenS/2; i++ { 58 | if nodeStack[i] == nil || nodeStack[lenS-1-i] == nil { 59 | if nodeStack[i] == nil && nodeStack[lenS-1-i] == nil { 60 | continue 61 | } 62 | return false 63 | } else if nodeStack[i].Val == nodeStack[lenS-1-i].Val { 64 | tmpStack = append([]*TreeNode{nodeStack[i].Left, nodeStack[i].Right}, tmpStack...) 65 | tmpStack = append(tmpStack, nodeStack[lenS-1-i].Left, nodeStack[lenS-1-i].Right) 66 | } else { 67 | return false 68 | } 69 | } 70 | nodeStack = tmpStack 71 | } 72 | return true 73 | } 74 | 75 | const ( 76 | eightGB = 8 << 30 77 | ) 78 | 79 | func main() { 80 | // 申请八个G内存 81 | p := make([]byte, eightGB) 82 | 83 | // 显示内存占用情况 84 | var m runtime.MemStats 85 | runtime.ReadMemStats(&m) 86 | fmt.Printf("Alloc = %v MB\n", m.Alloc/1024/1024) 87 | fmt.Printf("TotalAlloc = %v MB\n", m.TotalAlloc/1024/1024) 88 | fmt.Printf("Sys = %v MB\n", m.Sys/1024/1024) 89 | 90 | // 释放内存 91 | ptr := (*uintptr)(unsafe.Pointer(&p)) 92 | h := (*reflect.SliceHeader)(unsafe.Pointer(ptr)) 93 | h.Data = 0 94 | h.Len = 0 95 | h.Cap = 0 96 | p = nil 97 | 98 | // 显示内存占用情况 99 | runtime.ReadMemStats(&m) 100 | fmt.Printf("Alloc = %v MB\n", m.Alloc/1024/1024) 101 | fmt.Printf("TotalAlloc = %v MB\n", m.TotalAlloc/1024/1024) 102 | fmt.Printf("Sys = %v MB\n", m.Sys/1024/1024) 103 | } 104 | -------------------------------------------------------------------------------- /day0504/Day16 二叉树part03.md: -------------------------------------------------------------------------------- 1 | # Day16 二叉树part03 2 | ## 104.二叉树的最大深度 3 | 1. 递归 4 | ```go 5 | func maxDepth(root *TreeNode) int { 6 | if root == nil { 7 | return 0 8 | } 9 | leftD := maxDepth(root.Left) 10 | rightD := maxDepth(root.Right) 11 | if leftD > rightD { 12 | return 1 + leftD 13 | } else { 14 | return 1 + rightD 15 | } 16 | } 17 | ``` 18 | ## 111.二叉树的最小深度 19 | 1. 递归 20 | ```go 21 | func minDepth(root *TreeNode) int { 22 | if root == nil { 23 | return 0 24 | } 25 | leftD := minDepth(root.Left) 26 | rightD := minDepth(root.Right) 27 | if leftD == 0 && rightD == 0 { 28 | return 1 29 | } else if leftD == 0 { 30 | return 1 + rightD 31 | } else if rightD == 0 { 32 | return 1 + leftD 33 | } else if rightD < leftD { 34 | return 1 + rightD 35 | } else { 36 | return 1 + leftD 37 | } 38 | } 39 | ``` 40 | 41 | ## 222.完全二叉树的节点个数 42 | 1. 递归 43 | ```go 44 | func getMin(root *TreeNode) int { 45 | if root == nil { 46 | return 0 47 | } 48 | return getMin(root.Left) + 1 49 | } 50 | 51 | func getMax(root *TreeNode) int { 52 | if root == nil { 53 | return 0 54 | } 55 | return getMax(root.Right) + 1 56 | } 57 | 58 | func countNodes(root *TreeNode) int { 59 | if root == nil { 60 | return 0 61 | } 62 | min := getMin(root) 63 | max := getMax(root) 64 | fmt.Println(min, max) 65 | if max == min { 66 | return 1< rightD { 15 | return 1 + leftD 16 | } else { 17 | return 1 + rightD 18 | } 19 | } 20 | 21 | func minDepth(root *TreeNode) int { 22 | if root == nil { 23 | return 0 24 | } 25 | leftD := minDepth(root.Left) 26 | rightD := minDepth(root.Right) 27 | if leftD == 0 && rightD == 0 { 28 | return 1 29 | } else if leftD == 0 { 30 | return 1 + rightD 31 | } else if rightD == 0 { 32 | return 1 + leftD 33 | } else if rightD < leftD { 34 | return 1 + rightD 35 | } else { 36 | return 1 + leftD 37 | } 38 | } 39 | 40 | func getMin(root *TreeNode) int { 41 | if root == nil { 42 | return 0 43 | } 44 | return getMin(root.Left) + 1 45 | } 46 | 47 | func getMax(root *TreeNode) int { 48 | if root == nil { 49 | return 0 50 | } 51 | return getMax(root.Right) + 1 52 | } 53 | 54 | func countNodes(root *TreeNode) int { 55 | if root == nil { 56 | return 0 57 | } 58 | min := getMin(root) 59 | max := getMax(root) 60 | fmt.Println(min, max) 61 | if max == min { 62 | return 1< rightD { 15 | if leftD-rightD > 1 { 16 | return -1 17 | } 18 | return 1 + leftD 19 | } else { 20 | if rightD-leftD > 1 { 21 | return -1 22 | } 23 | return 1 + rightD 24 | } 25 | } 26 | } 27 | 28 | func isBalanced(root *TreeNode) bool { 29 | if root == nil { 30 | return true 31 | } else { 32 | res := BalancedDepth(root) 33 | if res == -1 { 34 | return false 35 | } else { 36 | return true 37 | } 38 | } 39 | } 40 | ``` 41 | ## 257. 二叉树的所有路径 42 | 1. 递归 43 | ```go 44 | func binaryTreePaths(root *TreeNode) []string { 45 | var res []string 46 | if root == nil { 47 | return res 48 | } 49 | if root.Left == nil && root.Right == nil { 50 | return append(res, strconv.Itoa(root.Val)) 51 | } 52 | if root.Left != nil { 53 | Left := binaryTreePaths(root.Left) 54 | for i := 0; i < len(Left); i++ { 55 | Left[i] = strconv.Itoa(root.Val) + "->" + Left[i] 56 | } 57 | res = append(res, Left...) 58 | } 59 | if root.Right != nil { 60 | Right := binaryTreePaths(root.Right) 61 | for i := 0; i < len(Right); i++ { 62 | Right[i] = strconv.Itoa(root.Val) + "->" + Right[i] 63 | } 64 | res = append(res, Right...) 65 | } 66 | return res 67 | } 68 | ``` 69 | ## 404.左叶子之和 70 | 1. 答案是两层搜索通过判断父节点确定是否为左叶子,也可以重写下函数判断当前节点是不是左子树遍历来的 71 | ```go 72 | func getSum(root *TreeNode, isLeft bool) int { 73 | if root.Left == nil && root.Right == nil { 74 | if isLeft == true { 75 | return root.Val 76 | } else { 77 | return 0 78 | } 79 | } else { 80 | sum := 0 81 | if root.Left != nil { 82 | sum += getSum(root.Left, true) 83 | } 84 | if root.Right != nil { 85 | sum += getSum(root.Right, false) 86 | } 87 | return sum 88 | } 89 | } 90 | 91 | func sumOfLeftLeaves(root *TreeNode) int { 92 | return getSum(root, false) 93 | } 94 | ``` -------------------------------------------------------------------------------- /day0505/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | "strconv" 6 | ) 7 | 8 | func BalancedDepth(root *TreeNode) int { 9 | if root == nil { 10 | return 0 11 | } else { 12 | leftD := BalancedDepth(root.Left) 13 | rightD := BalancedDepth(root.Right) 14 | if leftD == -1 || rightD == -1 { 15 | return -1 16 | } 17 | if leftD > rightD { 18 | if leftD-rightD > 1 { 19 | return -1 20 | } 21 | return 1 + leftD 22 | } else { 23 | if rightD-leftD > 1 { 24 | return -1 25 | } 26 | return 1 + rightD 27 | } 28 | } 29 | } 30 | 31 | func isBalanced(root *TreeNode) bool { 32 | if root == nil { 33 | return true 34 | } else { 35 | res := BalancedDepth(root) 36 | if res == -1 { 37 | return false 38 | } else { 39 | return true 40 | } 41 | } 42 | } 43 | 44 | func binaryTreePaths(root *TreeNode) []string { 45 | var res []string 46 | if root == nil { 47 | return res 48 | } 49 | if root.Left == nil && root.Right == nil { 50 | return append(res, strconv.Itoa(root.Val)) 51 | } 52 | if root.Left != nil { 53 | Left := binaryTreePaths(root.Left) 54 | for i := 0; i < len(Left); i++ { 55 | Left[i] = strconv.Itoa(root.Val) + "->" + Left[i] 56 | } 57 | res = append(res, Left...) 58 | } 59 | if root.Right != nil { 60 | Right := binaryTreePaths(root.Right) 61 | for i := 0; i < len(Right); i++ { 62 | Right[i] = strconv.Itoa(root.Val) + "->" + Right[i] 63 | } 64 | res = append(res, Right...) 65 | } 66 | return res 67 | } 68 | 69 | func getSum(root *TreeNode, isLeft bool) int { 70 | if root.Left == nil && root.Right == nil { 71 | if isLeft == true { 72 | return root.Val 73 | } else { 74 | return 0 75 | } 76 | } else { 77 | sum := 0 78 | if root.Left != nil { 79 | sum += getSum(root.Left, true) 80 | } 81 | if root.Right != nil { 82 | sum += getSum(root.Right, false) 83 | } 84 | return sum 85 | } 86 | } 87 | 88 | func sumOfLeftLeaves(root *TreeNode) int { 89 | return getSum(root, false) 90 | } 91 | -------------------------------------------------------------------------------- /day0506/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | ) 6 | 7 | func findBottomLeftValue(root *TreeNode) int { 8 | nodeStack := []*TreeNode{root} 9 | tmpL := 0 10 | tmpN := &TreeNode{ 11 | Val: 0, 12 | Left: nil, 13 | Right: nil, 14 | } 15 | for len(nodeStack) != 0 { 16 | tmpL = len(nodeStack) 17 | head := nodeStack[0] 18 | for i := 0; i < tmpL; i++ { 19 | tmpN = nodeStack[0] 20 | nodeStack = nodeStack[1:] 21 | if tmpN.Left != nil { 22 | nodeStack = append(nodeStack, tmpN.Left) 23 | } 24 | if tmpN.Right != nil { 25 | nodeStack = append(nodeStack, tmpN.Right) 26 | } 27 | } 28 | if len(nodeStack) == 0 { 29 | return head.Val 30 | } 31 | } 32 | return 0 33 | } 34 | 35 | func dfs(root *TreeNode, targetSum, curSum int) bool { 36 | if root == nil { 37 | return false 38 | } 39 | curSum = root.Val + curSum 40 | if root.Left == nil && root.Right == nil { 41 | if curSum != targetSum { 42 | return false 43 | } else { 44 | return true 45 | } 46 | } 47 | return dfs(root.Left, targetSum, curSum) || dfs(root.Right, targetSum, curSum) 48 | } 49 | 50 | func hasPathSum(root *TreeNode, targetSum int) bool { 51 | return dfs(root, targetSum, 0) 52 | } 53 | 54 | func dfsII(root *TreeNode, targetSum, curSum int, curS *[]int, curSS *[][]int) { 55 | curSum = curSum + root.Val 56 | *curS = append(*curS, root.Val) 57 | if root.Left == nil && root.Right == nil { 58 | if curSum == targetSum { 59 | copyRes := make([]int, len(*curS)) 60 | copy(copyRes, *curS) 61 | *curSS = append(*curSS, copyRes) 62 | } else { 63 | return 64 | } 65 | } else { 66 | if root.Left != nil { 67 | dfsII(root.Left, targetSum, curSum, curS, curSS) 68 | *curS = (*curS)[:len(*curS)-1] 69 | } 70 | if root.Right != nil { 71 | dfsII(root.Right, targetSum, curSum, curS, curSS) 72 | *curS = (*curS)[:len(*curS)-1] 73 | } 74 | } 75 | 76 | } 77 | 78 | func pathSum(root *TreeNode, targetSum int) [][]int { 79 | 80 | curSS := make([][]int, 0) 81 | curS := make([]int, 0) 82 | if root == nil { 83 | return curSS 84 | } 85 | dfsII(root, targetSum, 0, &curS, &curSS) 86 | return curSS 87 | } 88 | 89 | func buildTreePI(preorder []int, inorder []int) *TreeNode { 90 | if len(preorder) == 0 { 91 | return nil 92 | } 93 | root := &TreeNode{ 94 | Val: preorder[0], 95 | Left: nil, 96 | Right: nil, 97 | } 98 | mid := preorder[0] 99 | for i := 0; i < len(inorder); i++ { 100 | if inorder[i] == mid { 101 | root.Left = buildTreePI(preorder[1:i+1], inorder[:i]) 102 | root.Right = buildTreePI(preorder[i+1:], inorder[i+1:]) 103 | } 104 | } 105 | return root 106 | } 107 | 108 | func buildTreeIP(inorder []int, postorder []int) *TreeNode { 109 | if len(postorder) == 0 { 110 | return nil 111 | } 112 | root := &TreeNode{ 113 | Val: postorder[len(postorder)-1], 114 | Left: nil, 115 | Right: nil, 116 | } 117 | mid := postorder[len(postorder)-1] 118 | for i := 0; i < len(inorder); i++ { 119 | if inorder[i] == mid { 120 | root.Left = buildTreePI(inorder[:i], postorder[:i]) 121 | root.Right = buildTreePI(inorder[i+1:], postorder[i:len(postorder)-1]) 122 | } 123 | } 124 | return root 125 | } 126 | -------------------------------------------------------------------------------- /day0508/Day20二叉树part06.md: -------------------------------------------------------------------------------- 1 | # Day20二叉树part06 2 | 3 | ## 654.最大二叉树 4 | 1. 递归 5 | ```go 6 | func constructMaximumBinaryTree(nums []int) *TreeNode { 7 | if len(nums) == 0 { 8 | return nil 9 | } 10 | root := &TreeNode{ 11 | Val: 0, 12 | Left: nil, 13 | Right: nil, 14 | } 15 | max := -1 16 | loc := -1 17 | for i := 0; i < len(nums); i++ { 18 | if nums[i] > max { 19 | max = nums[i] 20 | loc = i 21 | } 22 | } 23 | root.Val = max 24 | root.Left = constructMaximumBinaryTree(nums[:loc]) 25 | root.Right = constructMaximumBinaryTree(nums[loc+1:]) 26 | return root 27 | } 28 | ``` 29 | ## 617.合并二叉树 30 | 1. 递归 31 | ```go 32 | func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode { 33 | if root1 == nil && root2 == nil { 34 | return nil 35 | } else if root1 != nil && root2 != nil { 36 | root := &TreeNode{ 37 | Val: root1.Val + root2.Val, 38 | Left: mergeTrees(root1.Left, root2.Left), 39 | Right: mergeTrees(root1.Right, root2.Right), 40 | } 41 | return root 42 | } else if root1 == nil { 43 | return root2 44 | } else { 45 | return root1 46 | } 47 | } 48 | ``` 49 | ## 700.二叉搜索树中的搜索 50 | 1. 递归 51 | ```go 52 | func searchBST(root *TreeNode, val int) *TreeNode { 53 | if root == nil { 54 | return nil 55 | } 56 | if root.Val == val { 57 | return root 58 | } 59 | if root.Left != nil { 60 | res := searchBST(root.Left, val) 61 | if res != nil { 62 | return res 63 | } 64 | } 65 | if root.Right != nil { 66 | res := searchBST(root.Right, val) 67 | if res != nil { 68 | return res 69 | } 70 | } 71 | return nil 72 | } 73 | ``` 74 | ## 98.验证二叉搜索树 75 | 1. 迭代 76 | ```go 77 | func isValidBST(root *TreeNode) bool { 78 | nodeStack := list.New() 79 | var resS []int 80 | nodeStack.PushBack(root) 81 | for nodeStack.Len() > 0 { 82 | tmpN := nodeStack.Back() 83 | nodeStack.Remove(tmpN) 84 | if tmpN.Value == nil { 85 | tmpN = nodeStack.Back() 86 | nodeStack.Remove(tmpN) 87 | resS = append(resS, tmpN.Value.(*TreeNode).Val) 88 | continue 89 | } 90 | if tmpN.Value.(*TreeNode).Right != nil { 91 | nodeStack.PushBack(tmpN.Value.(*TreeNode).Right) 92 | } 93 | nodeStack.PushBack(tmpN.Value.(*TreeNode)) 94 | nodeStack.PushBack(nil) 95 | if tmpN.Value.(*TreeNode).Left != nil { 96 | nodeStack.PushBack(tmpN.Value.(*TreeNode).Left) 97 | } 98 | } 99 | for i := 0; i < len(resS)-1; i++ { 100 | if resS[i] >= resS[i+1] { 101 | return false 102 | } 103 | } 104 | return true 105 | } 106 | ``` 107 | 2. 递归 108 | ```go 109 | func BST(pre, cur **TreeNode) bool { 110 | if *cur == nil { 111 | return true 112 | } 113 | left := BST(pre, &(*cur).Left) 114 | if (*pre) != nil && (*cur).Val <= (*pre).Val { 115 | return false 116 | } 117 | *pre = *cur 118 | right := BST(pre, &(*cur).Right) 119 | return left && right 120 | } 121 | 122 | func isValidBST(root *TreeNode) bool { 123 | var pre *TreeNode 124 | if root == nil { 125 | return true 126 | } 127 | return BST(&pre, &root) 128 | } 129 | ``` -------------------------------------------------------------------------------- /day0508/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | "container/ring" 6 | "fmt" 7 | ) 8 | 9 | func constructMaximumBinaryTree(nums []int) *TreeNode { 10 | if len(nums) == 0 { 11 | return nil 12 | } 13 | root := &TreeNode{ 14 | Val: 0, 15 | Left: nil, 16 | Right: nil, 17 | } 18 | max := -1 19 | loc := -1 20 | for i := 0; i < len(nums); i++ { 21 | if nums[i] > max { 22 | max = nums[i] 23 | loc = i 24 | } 25 | } 26 | root.Val = max 27 | root.Left = constructMaximumBinaryTree(nums[:loc]) 28 | root.Right = constructMaximumBinaryTree(nums[loc+1:]) 29 | return root 30 | } 31 | 32 | func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode { 33 | if root1 == nil && root2 == nil { 34 | return nil 35 | } else if root1 != nil && root2 != nil { 36 | root := &TreeNode{ 37 | Val: root1.Val + root2.Val, 38 | Left: mergeTrees(root1.Left, root2.Left), 39 | Right: mergeTrees(root1.Right, root2.Right), 40 | } 41 | return root 42 | } else if root1 == nil { 43 | return root2 44 | } else { 45 | return root1 46 | } 47 | } 48 | 49 | func searchBST(root *TreeNode, val int) *TreeNode { 50 | if root == nil { 51 | return nil 52 | } 53 | if root.Val == val { 54 | return root 55 | } 56 | if root.Left != nil { 57 | res := searchBST(root.Left, val) 58 | if res != nil { 59 | return res 60 | } 61 | } 62 | if root.Right != nil { 63 | res := searchBST(root.Right, val) 64 | if res != nil { 65 | return res 66 | } 67 | } 68 | return nil 69 | } 70 | 71 | func BST(pre, cur **TreeNode) bool { 72 | if *cur == nil { 73 | return true 74 | } 75 | left := BST(pre, &(*cur).Left) 76 | if (*pre) != nil && (*cur).Val <= (*pre).Val { 77 | return false 78 | } 79 | *pre = *cur 80 | right := BST(pre, &(*cur).Right) 81 | return left && right 82 | } 83 | 84 | func isValidBST(root *TreeNode) bool { 85 | var pre *TreeNode 86 | if root == nil { 87 | return true 88 | } 89 | return BST(&pre, &root) 90 | } 91 | 92 | /* 93 | [5,5,2,1,0] 94 | */ 95 | func jump(nums []int) int { 96 | numsL := len(nums) 97 | dp := make([]int, numsL) 98 | for i := 0; i < numsL; i++ { 99 | dp[i] = numsL 100 | } 101 | dp[numsL-1] = 0 102 | for i := numsL - 2; i >= 0; i-- { 103 | min := numsL 104 | for j := 0; j <= nums[i] && i+j <= (numsL-1); j++ { 105 | if 1+dp[i+j] < min { 106 | min = 1 + dp[i+j] 107 | } 108 | } 109 | dp[i] = min 110 | } 111 | return dp[0] 112 | } 113 | 114 | func main() { 115 | // 创建两个容量为3的Ring 116 | r1 := ring.New(3) 117 | for i := 1; i <= r1.Len(); i++ { 118 | 119 | r1.Value = i 120 | fmt.Println(r1) 121 | r1 = r1.Next() 122 | } 123 | 124 | r2 := ring.New(3) 125 | for i := 4; i <= r2.Len()+3; i++ { 126 | fmt.Println(r2) 127 | r2.Value = i 128 | r2 = r2.Next() 129 | } 130 | 131 | // 输出原始的Ring 132 | fmt.Println("Original rings:") 133 | printRing(r1) 134 | printRing(r2) 135 | 136 | // 将r2链接到r1的后面 137 | r1.Link(r2) 138 | fmt.Println("After linking r2 to r1:") 139 | printRing(r1) 140 | } 141 | 142 | // 打印Ring中的所有元素 143 | func printRing(r *ring.Ring) { 144 | r.Do(func(x interface{}) { 145 | fmt.Print(x, " ") 146 | }) 147 | fmt.Println() 148 | } 149 | -------------------------------------------------------------------------------- /day0509/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | "math" 6 | ) 7 | 8 | func abs(x int) int { 9 | if x < 0 { 10 | return -x 11 | } else { 12 | return x 13 | } 14 | } 15 | func getMinDfs(pre, cur **TreeNode, min *int) { 16 | if (*cur).Left != nil { 17 | getMinDfs(pre, &(*cur).Left, min) 18 | } 19 | if (*pre) != nil { 20 | sub := abs((*pre).Val - (*cur).Val) 21 | if sub < (*min) { 22 | *min = sub 23 | } 24 | } 25 | *pre = *cur 26 | if (*cur).Right != nil { 27 | getMinDfs(pre, &(*cur).Right, min) 28 | } 29 | } 30 | 31 | func getMinimumDifference(root *TreeNode) int { 32 | var pre *TreeNode 33 | res := math.MaxInt 34 | getMinDfs(&pre, &root, &res) 35 | return res 36 | } 37 | 38 | func findMode(root *TreeNode) []int { 39 | modeS := make([]int, 0) 40 | modeCount := 0 41 | curNum := 0 42 | curCount := 0 43 | var pre *TreeNode 44 | var dfsMode func(node *TreeNode) 45 | dfsMode = func(node *TreeNode) { 46 | if node.Left != nil { 47 | dfsMode(node.Left) 48 | } 49 | //fmt.Println(node.Val) 50 | if pre == nil { 51 | modeS = []int{node.Val} 52 | modeCount = curCount 53 | curNum = node.Val 54 | curCount = 1 55 | } else { 56 | if pre.Val == node.Val { 57 | curCount++ 58 | } else { 59 | if curCount > modeCount { 60 | modeS = []int{curNum} 61 | modeCount = curCount 62 | curNum = node.Val 63 | curCount = 1 64 | } else if curCount == modeCount { 65 | modeS = append(modeS, curNum) 66 | curNum = node.Val 67 | curCount = 1 68 | } else { 69 | curNum = node.Val 70 | curCount = 1 71 | } 72 | } 73 | } 74 | pre = node 75 | if node.Right != nil { 76 | dfsMode(node.Right) 77 | } 78 | } 79 | dfsMode(root) 80 | if modeS[len(modeS)-1] != curNum { 81 | if curCount > modeCount { 82 | modeS = []int{curNum} 83 | } else if curCount == modeCount { 84 | modeS = append(modeS, curNum) 85 | } 86 | } 87 | return modeS 88 | } 89 | 90 | /* 91 | find p = 1 92 | find q = 2 93 | */ 94 | 95 | func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { 96 | var res *TreeNode 97 | var dfsCommonNode func(root, p, q *TreeNode) int 98 | dfsCommonNode = func(root, p, q *TreeNode) int { 99 | if root == nil { 100 | return -1 101 | } 102 | if root == p { 103 | left := dfsCommonNode(root.Left, p, q) 104 | if left == 2 { 105 | res = root 106 | return 0 107 | } 108 | right := dfsCommonNode(root.Right, p, q) 109 | if right == 2 { 110 | res = root 111 | return 0 112 | } 113 | return 1 114 | } else if root == q { 115 | left := dfsCommonNode(root.Left, p, q) 116 | if left == 1 { 117 | res = root 118 | return 0 119 | } 120 | right := dfsCommonNode(root.Right, p, q) 121 | if right == 1 { 122 | res = root 123 | return 0 124 | } 125 | return 2 126 | } else { 127 | left := dfsCommonNode(root.Left, p, q) 128 | if left == 0 { 129 | return 0 130 | } 131 | right := dfsCommonNode(root.Right, p, q) 132 | if right == 0 { 133 | return 0 134 | } 135 | if (left + right) == 3 { 136 | res = root 137 | return 0 138 | } 139 | if left == 1 || right == 1 { 140 | return 1 141 | } else if left == 2 || right == 2 { 142 | return 2 143 | } else { 144 | return -1 145 | } 146 | } 147 | } 148 | dfsCommonNode(root, p, q) 149 | return res 150 | } 151 | -------------------------------------------------------------------------------- /day0510/Day22二叉树part08.md: -------------------------------------------------------------------------------- 1 | ## Day22二叉树 2 | ## 235. 二叉搜索树的最近公共祖先 3 | 1. 递归 4 | ```go 5 | func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { 6 | var res *TreeNode 7 | var bigger *TreeNode 8 | var smaller *TreeNode 9 | if p.Val > q.Val { 10 | bigger = p 11 | smaller = q 12 | } else { 13 | bigger = q 14 | smaller = p 15 | } 16 | 17 | var dfs func(root, bigger, smaller *TreeNode) 18 | dfs = func(root, bigger, smaller *TreeNode) { 19 | if root.Val > bigger.Val { 20 | dfs(root.Left, bigger, smaller) 21 | } else if root.Val < smaller.Val { 22 | dfs(root.Right, bigger, smaller) 23 | } else { 24 | res = root 25 | return 26 | } 27 | } 28 | dfs(root, bigger, smaller) 29 | return res 30 | } 31 | ``` 32 | 2. 答案比较简练地递归 33 | ```go 34 | func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { 35 | if root == nil { 36 | return nil 37 | } 38 | for { 39 | if root.Val > p.Val && root.Val > q.Val { 40 | root = root.Left 41 | } 42 | if root.Val < p.Val && root.Val < q.Val { 43 | root = root.Right 44 | } 45 | if (root.Val - p.Val) * (root.Val - q.Val) <= 0 { 46 | return root 47 | } 48 | } 49 | return root 50 | } 51 | ``` 52 | 53 | ## 701.二叉搜索树中的插入操作 54 | 1. 愚蠢的从头遍历 55 | ```go 56 | func insertIntoBST(root *TreeNode, val int) *TreeNode { 57 | newNode := &TreeNode{Val: val} 58 | if root == nil { 59 | return newNode 60 | } 61 | var pre *TreeNode 62 | var dfs func(root *TreeNode, val int) 63 | dfs = func(root *TreeNode, val int) { 64 | if root == nil { 65 | return 66 | } 67 | if root.Left != nil { 68 | dfs(root.Left, val) 69 | } 70 | if pre != nil { 71 | if val < pre.Val { 72 | pre.Left = newNode 73 | pre = newNode 74 | return 75 | } else if val > pre.Val && val < root.Val { 76 | //fmt.Println("pre:", pre.Val, " root:", root.Val) 77 | newNode.Left = root.Left 78 | //newNode.Right = root.Right 79 | root.Left = newNode 80 | pre = newNode 81 | return 82 | } else if pre.Val >= val { 83 | return 84 | } 85 | } 86 | pre = root 87 | if root.Right != nil { 88 | dfs(root.Right, val) 89 | } 90 | } 91 | dfs(root, val) 92 | if pre.Val != val { 93 | newNode.Left = root 94 | return newNode 95 | } 96 | return root 97 | } 98 | ``` 99 | 2. 大佬的机智简明递归,恐怖如斯 100 | ```go 101 | func insertIntoBST(root *TreeNode, val int) *TreeNode { 102 | if root == nil { 103 | return &TreeNode{Val: val} 104 | } 105 | if val < root.Val { 106 | root.Left = insertIntoBST(root.Left, val) 107 | } else { 108 | root.Right = insertIntoBST(root.Right, val) 109 | } 110 | return root 111 | } 112 | ``` 113 | ## 450.删除二叉搜索树中的节点 114 | 1. 递归 115 | ```go 116 | func getRight(root *TreeNode) *TreeNode { 117 | if root == nil || root.Right == nil { 118 | return root 119 | } 120 | return getRight(root.Right) 121 | } 122 | 123 | func deleteNode(root *TreeNode, key int) *TreeNode { 124 | if root == nil { 125 | return nil 126 | } 127 | if root.Val == key { 128 | if root.Left == nil { 129 | return root.Right 130 | } else { 131 | left := getRight(root.Left) 132 | left.Right = root.Right 133 | } 134 | root = root.Left 135 | } else if root.Val < key { 136 | root.Right = deleteNode(root.Right, key) 137 | } else { 138 | root.Left = deleteNode(root.Left, key) 139 | } 140 | return root 141 | } 142 | ``` -------------------------------------------------------------------------------- /day0510/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | ) 6 | 7 | func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { 8 | var res *TreeNode 9 | var bigger *TreeNode 10 | var smaller *TreeNode 11 | if p.Val > q.Val { 12 | bigger = p 13 | smaller = q 14 | } else { 15 | bigger = q 16 | smaller = p 17 | } 18 | 19 | var dfs func(root, bigger, smaller *TreeNode) 20 | dfs = func(root, bigger, smaller *TreeNode) { 21 | if root.Val > bigger.Val { 22 | dfs(root.Left, bigger, smaller) 23 | } else if root.Val < smaller.Val { 24 | dfs(root.Right, bigger, smaller) 25 | } else { 26 | res = root 27 | return 28 | } 29 | } 30 | dfs(root, bigger, smaller) 31 | return res 32 | } 33 | 34 | func insertIntoBST(root *TreeNode, val int) *TreeNode { 35 | if root == nil { 36 | return &TreeNode{Val: val} 37 | } 38 | if val < root.Val { 39 | root.Left = insertIntoBST(root.Left, val) 40 | } else { 41 | root.Right = insertIntoBST(root.Right, val) 42 | } 43 | return root 44 | } 45 | 46 | func getRight(root *TreeNode) *TreeNode { 47 | if root == nil || root.Right == nil { 48 | return root 49 | } 50 | return getRight(root.Right) 51 | } 52 | 53 | func deleteNode(root *TreeNode, key int) *TreeNode { 54 | if root == nil { 55 | return nil 56 | } 57 | if root.Val == key { 58 | if root.Left == nil { 59 | return root.Right 60 | } else { 61 | left := getRight(root.Left) 62 | left.Right = root.Right 63 | } 64 | root = root.Left 65 | } else if root.Val < key { 66 | root.Right = deleteNode(root.Right, key) 67 | } else { 68 | root.Left = deleteNode(root.Left, key) 69 | } 70 | return root 71 | } 72 | -------------------------------------------------------------------------------- /day0511/Day23二叉树part03.md: -------------------------------------------------------------------------------- 1 | # Day23二叉树part03 2 | ## 669. 修剪二叉搜索树 3 | 1. 递归 4 | ```go 5 | func trimBST(root *TreeNode, low int, high int) *TreeNode { 6 | if root == nil { 7 | return root 8 | } 9 | if root.Val < low { 10 | return trimBST(root.Right, low, high) 11 | } else if root.Val > high { 12 | return trimBST(root.Left, low, high) 13 | } else if root.Val == low { 14 | root.Left = nil 15 | root.Right = trimBST(root.Right, low, high) 16 | return root 17 | } else if root.Val == high { 18 | root.Left = trimBST(root.Left, low, high) 19 | root.Right = nil 20 | return root 21 | } else { 22 | root.Left = trimBST(root.Left, low, high) 23 | root.Right = trimBST(root.Right, low, high) 24 | return root 25 | } 26 | } 27 | ``` 28 | ## 108.将有序数组转换为二叉搜索树 29 | 1. 递归 30 | ```go 31 | func sortedArrayToBST(nums []int) *TreeNode { 32 | lenN := len(nums) 33 | if lenN == 0 { 34 | return nil 35 | } 36 | res := &TreeNode{ 37 | Val: nums[lenN/2], 38 | Left: nil, 39 | Right: nil, 40 | } 41 | res.Left = sortedArrayToBST(nums[0 : lenN/2]) 42 | res.Right = sortedArrayToBST(nums[lenN/2+1:]) 43 | return res 44 | } 45 | ``` 46 | ## 538.把二叉搜索树转换为累加树 47 | 1. 递归 48 | ```go 49 | func convertBST(root *TreeNode) *TreeNode { 50 | if root == nil { 51 | return root 52 | } 53 | sum := 0 54 | var sumDFS func(root *TreeNode) 55 | sumDFS = func(root *TreeNode) { 56 | if root.Right != nil { 57 | sumDFS(root.Right) 58 | } 59 | sum += root.Val 60 | root.Val = sum 61 | if root.Left != nil { 62 | sumDFS(root.Left) 63 | } 64 | } 65 | sumDFS(root) 66 | return root 67 | } 68 | ``` -------------------------------------------------------------------------------- /day0511/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | ) 6 | 7 | func trimBST(root *TreeNode, low int, high int) *TreeNode { 8 | if root == nil { 9 | return root 10 | } 11 | if root.Val < low { 12 | return trimBST(root.Right, low, high) 13 | } else if root.Val > high { 14 | return trimBST(root.Left, low, high) 15 | } else if root.Val == low { 16 | root.Left = nil 17 | root.Right = trimBST(root.Right, low, high) 18 | return root 19 | } else if root.Val == high { 20 | root.Left = trimBST(root.Left, low, high) 21 | root.Right = nil 22 | return root 23 | } else { 24 | root.Left = trimBST(root.Left, low, high) 25 | root.Right = trimBST(root.Right, low, high) 26 | return root 27 | } 28 | } 29 | 30 | func sortedArrayToBST(nums []int) *TreeNode { 31 | lenN := len(nums) 32 | if lenN == 0 { 33 | return nil 34 | } 35 | res := &TreeNode{ 36 | Val: nums[lenN/2], 37 | Left: nil, 38 | Right: nil, 39 | } 40 | res.Left = sortedArrayToBST(nums[0 : lenN/2]) 41 | res.Right = sortedArrayToBST(nums[lenN/2+1:]) 42 | return res 43 | } 44 | 45 | func convertBST(root *TreeNode) *TreeNode { 46 | if root == nil { 47 | return root 48 | } 49 | sum := 0 50 | var sumDFS func(root *TreeNode) 51 | sumDFS = func(root *TreeNode) { 52 | if root.Right != nil { 53 | sumDFS(root.Right) 54 | } 55 | sum += root.Val 56 | root.Val = sum 57 | if root.Left != nil { 58 | sumDFS(root.Left) 59 | } 60 | } 61 | sumDFS(root) 62 | return root 63 | } 64 | -------------------------------------------------------------------------------- /day0512/Day24回溯算法part01.md: -------------------------------------------------------------------------------- 1 | # Day24回溯算法part01 2 | 3 | ## 77. 组合 4 | 1. 回溯 5 | ```go 6 | func combine(n int, k int) [][]int { 7 | var res [][]int 8 | var tmpS []int 9 | var dfs func(m, n, k int, s *[]int) 10 | dfs = func(m, n, k int, s *[]int) { 11 | if len(*s) == k { 12 | fmt.Println(res) 13 | tmp := make([]int, len(*s)) 14 | copy(tmp, *s) 15 | res = append(res, tmp) 16 | return 17 | } 18 | for i := m; i <= n-(k-len(*s))+1; i++ { 19 | fmt.Println("i:", i, " m:", m, " n:", n, " s:", *s) 20 | *s = append(*s, i) 21 | dfs(i+1, n, k, s) 22 | *s = (*s)[:len(*s)-1] 23 | } 24 | } 25 | dfs(1, n, k, &tmpS) 26 | return res 27 | } 28 | ``` 29 | 2. 不用指针或全局变量 30 | ```go 31 | func combine(n int, k int) [][]int { 32 | var res [][]int 33 | var tmpS []int 34 | var dfs func(m, n, k int, s []int) 35 | dfs = func(m, n, k int, s []int) { 36 | if len(s) == k { 37 | fmt.Println(res) 38 | tmp := make([]int, len(s)) 39 | copy(tmp, s) 40 | res = append(res, tmp) 41 | return 42 | } 43 | for i := m; i <= n-(k-len(s))+1; i++ { 44 | fmt.Println("i:", i, " m:", m, " n:", n, " s:", s) 45 | s = append(s, i) 46 | dfs(i+1, n, k, s) 47 | s = (s)[:len(s)-1] 48 | } 49 | } 50 | dfs(1, n, k, tmpS) 51 | return res 52 | } 53 | ``` -------------------------------------------------------------------------------- /day0512/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | [0,1,2,3,4,5,6,7,8] 7 | [1,3,] k=5 l=2 8 | 4~8 6 k-l=3 n-3=5+1 9 | */ 10 | func combine(n int, k int) [][]int { 11 | var res [][]int 12 | var tmpS []int 13 | var dfs func(m, n, k int, s []int) 14 | dfs = func(m, n, k int, s []int) { 15 | if len(s) == k { 16 | fmt.Println(res) 17 | tmp := make([]int, len(s)) 18 | copy(tmp, s) 19 | res = append(res, tmp) 20 | return 21 | } 22 | for i := m; i <= n-(k-len(s))+1; i++ { 23 | fmt.Println("i:", i, " m:", m, " n:", n, " s:", s) 24 | s = append(s, i) 25 | dfs(i+1, n, k, s) 26 | s = (s)[:len(s)-1] 27 | } 28 | } 29 | dfs(1, n, k, tmpS) 30 | return res 31 | } 32 | -------------------------------------------------------------------------------- /day0513/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | k=4,n=15 9 | [1,2,] 10 | 6,6 11 | [x+l-1+x]l/2 n || max < n { 29 | return false 30 | } 31 | return true 32 | }(k, n); !ifExist { 33 | return res 34 | } 35 | tmpS := make([]int, 0) 36 | tmpSum := 0 37 | var BT func(m, k, n int) 38 | BT = func(m, k, n int) { 39 | //fmt.Println(" m:", m, " k:", k, " n:", n, " tmpSum", tmpSum) 40 | //fmt.Println(tmpS) 41 | if len(tmpS) == k { 42 | if tmpSum == n { 43 | copyS := make([]int, k) 44 | copy(copyS, tmpS) 45 | res = append(res, copyS) 46 | } 47 | return 48 | } 49 | 50 | lim := (2*n - 2*tmpSum - (k-len(tmpS))*(k-len(tmpS)) + (k - len(tmpS))) / (2 * (k - len(tmpS))) 51 | if lim > 9 { 52 | lim = 9 53 | } 54 | //fmt.Println(" lim:", lim, " (k - len(tmpS)):", k-len(tmpS)) 55 | for i := m; i <= lim; i++ { 56 | tmpS = append(tmpS, i) 57 | tmpSum += i 58 | BT(i+1, k, n) 59 | tmpS = tmpS[:len(tmpS)-1] 60 | tmpSum -= i 61 | } 62 | 63 | } 64 | BT(1, k, n) 65 | return res 66 | } 67 | 68 | func letterCombinations(digits string) []string { 69 | var res []string 70 | lenD := len(digits) 71 | if lenD == 0 { 72 | return res 73 | } 74 | var tmpS []byte 75 | var BT func(digits string, idx int) 76 | BT = func(digits string, idx int) { 77 | fmt.Println(int(digits[idx])) 78 | if idx == lenD { 79 | res = append(res, string(tmpS)) 80 | return 81 | } 82 | switch digits[idx] { 83 | case '7': 84 | for i := 0; i < 4; i++ { 85 | tmpS = append(tmpS, byte(int('p')+i)) 86 | BT(digits, idx+1) 87 | tmpS = tmpS[:len(tmpS)-1] 88 | } 89 | case '8': 90 | for i := 0; i < 3; i++ { 91 | tmpS = append(tmpS, byte(int('t')+i)) 92 | BT(digits, idx+1) 93 | tmpS = tmpS[:len(tmpS)-1] 94 | } 95 | case '9': 96 | for i := 0; i < 4; i++ { 97 | tmpS = append(tmpS, byte(int('w')+i)) 98 | BT(digits, idx+1) 99 | tmpS = tmpS[:len(tmpS)-1] 100 | } 101 | default: 102 | for i := 0; i < 3; i++ { 103 | tmpS = append(tmpS, byte((int(digits[idx])-50)*3+97+i)) 104 | BT(digits, idx+1) 105 | tmpS = tmpS[:len(tmpS)-1] 106 | } 107 | } 108 | } 109 | BT(digits, 0) 110 | return res 111 | } 112 | 113 | func main() { 114 | sInt := "0123456789" 115 | for i := 0; i < len(sInt); i++ { 116 | fmt.Println(i, ":", sInt[i]) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /day0516/Day28回溯算法part04.md: -------------------------------------------------------------------------------- 1 | # Day28回溯算法part04 2 | 3 | ## 93.复原IP地址 4 | 1. 回溯 5 | ```go 6 | func restoreIpAddresses(s string) []string { 7 | var res []string 8 | if len(s) < 4 { 9 | return res 10 | } 11 | var temS []string 12 | var ifIP func(s string) bool 13 | ifIP = func(s string) bool { 14 | if len(s) != 1 && s[0] == '0' { 15 | return false 16 | } 17 | numS, err := strconv.Atoi(s) 18 | if err != nil { 19 | panic(err) 20 | } 21 | if numS > 255 { 22 | return false 23 | } 24 | return true 25 | } 26 | var BT func(s string, idx int) 27 | BT = func(s string, idx int) { 28 | if len(temS) == 4 { 29 | ttS := "" 30 | for i := 0; i < len(temS); i++ { 31 | if i == 3 { 32 | ttS += temS[i] 33 | } else { 34 | ttS += temS[i] + "." 35 | } 36 | } 37 | res = append(res, ttS) 38 | } 39 | if (len(s)-idx) > (3*(4-len(temS))) || (len(s)-idx) < (4-len(temS)) { 40 | return 41 | } 42 | if len(temS) == 3 { 43 | if ifIP(s[idx:]) { 44 | temS = append(temS, s[idx:]) 45 | BT(s, idx) 46 | temS = temS[:len(temS)-1] 47 | } 48 | } else { 49 | for i := idx; i < len(s) && i < idx+3; i++ { 50 | if ifIP(s[idx : i+1]) { 51 | temS = append(temS, s[idx:i+1]) 52 | BT(s, i+1) 53 | temS = temS[:len(temS)-1] 54 | } 55 | } 56 | } 57 | } 58 | BT(s, 0) 59 | return res 60 | } 61 | ``` 62 | ## 78.子集 63 | 1. 回溯 64 | ```go 65 | func subsets(nums []int) [][]int { 66 | res := [][]int{{}} 67 | numsL := len(nums) 68 | var tmpS []int 69 | var BT func(nums []int, idx int) 70 | BT = func(nums []int, idx int) { 71 | for i := idx; i < numsL; i++ { 72 | tmpS = append(tmpS, nums[i]) 73 | copyS := make([]int, len(tmpS)) 74 | copy(copyS, tmpS) 75 | res = append(res, copyS) 76 | BT(nums, i+1) 77 | tmpS = tmpS[:len(tmpS)-1] 78 | } 79 | } 80 | BT(nums, 0) 81 | return res 82 | } 83 | ``` 84 | 85 | ## 90.子集II 86 | 1. 回溯 87 | ```go 88 | func subsetsWithDup(nums []int) [][]int { 89 | sort.Ints(nums) 90 | res := [][]int{{}} 91 | numsL := len(nums) 92 | var tmpS []int 93 | var BT func(nums []int, idx int) 94 | BT = func(nums []int, idx int) { 95 | for i := idx; i < numsL; { 96 | tmpS = append(tmpS, nums[i]) 97 | copyS := make([]int, len(tmpS)) 98 | copy(copyS, tmpS) 99 | res = append(res, copyS) 100 | BT(nums, i+1) 101 | tmpS = tmpS[:len(tmpS)-1] 102 | i++ 103 | for i < numsL { 104 | if nums[i] == nums[i-1] { 105 | i++ 106 | continue 107 | } 108 | break 109 | } 110 | } 111 | } 112 | BT(nums, 0) 113 | return res 114 | } 115 | ``` -------------------------------------------------------------------------------- /day0516/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | "strconv" 7 | ) 8 | 9 | func restoreIpAddresses(s string) []string { 10 | var res []string 11 | if len(s) < 4 { 12 | return res 13 | } 14 | var temS []string 15 | var ifIP func(s string) bool 16 | ifIP = func(s string) bool { 17 | if len(s) != 1 && s[0] == '0' { 18 | return false 19 | } 20 | numS, err := strconv.Atoi(s) 21 | if err != nil { 22 | panic(err) 23 | } 24 | if numS > 255 { 25 | return false 26 | } 27 | return true 28 | } 29 | var BT func(s string, idx int) 30 | BT = func(s string, idx int) { 31 | if len(temS) == 4 { 32 | ttS := "" 33 | for i := 0; i < len(temS); i++ { 34 | if i == 3 { 35 | ttS += temS[i] 36 | } else { 37 | ttS += temS[i] + "." 38 | } 39 | } 40 | res = append(res, ttS) 41 | } 42 | if (len(s)-idx) > (3*(4-len(temS))) || (len(s)-idx) < (4-len(temS)) { 43 | return 44 | } 45 | if len(temS) == 3 { 46 | if ifIP(s[idx:]) { 47 | temS = append(temS, s[idx:]) 48 | BT(s, idx) 49 | temS = temS[:len(temS)-1] 50 | } 51 | } else { 52 | for i := idx; i < len(s) && i < idx+3; i++ { 53 | if ifIP(s[idx : i+1]) { 54 | temS = append(temS, s[idx:i+1]) 55 | BT(s, i+1) 56 | temS = temS[:len(temS)-1] 57 | } 58 | } 59 | } 60 | } 61 | BT(s, 0) 62 | return res 63 | } 64 | 65 | /* 66 | [1,2,3,4,5,6] 67 | 123 124 125 68 | */ 69 | func subsets(nums []int) [][]int { 70 | res := [][]int{{}} 71 | numsL := len(nums) 72 | var tmpS []int 73 | var BT func(nums []int, idx int) 74 | BT = func(nums []int, idx int) { 75 | for i := idx; i < numsL; i++ { 76 | tmpS = append(tmpS, nums[i]) 77 | copyS := make([]int, len(tmpS)) 78 | copy(copyS, tmpS) 79 | res = append(res, copyS) 80 | BT(nums, i+1) 81 | tmpS = tmpS[:len(tmpS)-1] 82 | } 83 | } 84 | BT(nums, 0) 85 | return res 86 | } 87 | func subsetsWithDup(nums []int) [][]int { 88 | sort.Ints(nums) 89 | res := [][]int{{}} 90 | numsL := len(nums) 91 | var tmpS []int 92 | var BT func(nums []int, idx int) 93 | BT = func(nums []int, idx int) { 94 | for i := idx; i < numsL; { 95 | tmpS = append(tmpS, nums[i]) 96 | copyS := make([]int, len(tmpS)) 97 | copy(copyS, tmpS) 98 | res = append(res, copyS) 99 | BT(nums, i+1) 100 | tmpS = tmpS[:len(tmpS)-1] 101 | i++ 102 | for i < numsL { 103 | if nums[i] == nums[i-1] { 104 | i++ 105 | continue 106 | } 107 | break 108 | } 109 | } 110 | } 111 | BT(nums, 0) 112 | return res 113 | } 114 | 115 | func main() { 116 | res := [][]int{{}} 117 | fmt.Println(res) 118 | } 119 | -------------------------------------------------------------------------------- /day0517/Day29回溯算法part05.md: -------------------------------------------------------------------------------- 1 | # Day29回溯算法part05 2 | 3 | ## 491.递增子序列 4 | 1. 回溯 5 | ```go 6 | func findSubsequences(nums []int) [][]int { 7 | var res [][]int 8 | numsL := len(nums) 9 | var tmpS []int 10 | var BT func(nums []int, idx int) 11 | 12 | BT = func(nums []int, idx int) { 13 | usedS := make([]int, 201) 14 | for i := idx; i < numsL; i++ { 15 | if len(tmpS) > 0 && nums[i] < tmpS[len(tmpS)-1] || usedS[nums[i]+100] == 1 { 16 | continue 17 | } 18 | tmpS = append(tmpS, nums[i]) 19 | if len(tmpS) > 1 { 20 | copyS := make([]int, len(tmpS)) 21 | copy(copyS, tmpS) 22 | res = append(res, copyS) 23 | } 24 | BT(nums, i+1) 25 | tmpS = tmpS[:len(tmpS)-1] 26 | usedS[nums[i]+100] = 1 27 | } 28 | } 29 | BT(nums, 0) 30 | return res 31 | } 32 | ``` 33 | ## 46.全排列 34 | 1. 回溯 35 | ```go 36 | func permute(nums []int) [][]int { 37 | var res [][]int 38 | var tmpS []int 39 | lenN := len(nums) 40 | usedS := make([]int, lenN) 41 | var BT func(nums []int) 42 | BT = func(nums []int) { 43 | if len(tmpS) == lenN { 44 | copyS := make([]int, len(tmpS)) 45 | copy(copyS, tmpS) 46 | res = append(res, copyS) 47 | return 48 | } 49 | for i := 0; i < lenN; i++ { 50 | if usedS[i] == 1 { 51 | continue 52 | } 53 | tmpS = append(tmpS, nums[i]) 54 | usedS[i] = 1 55 | BT(nums) 56 | usedS[i] = 0 57 | tmpS = tmpS[:len(tmpS)-1] 58 | } 59 | } 60 | BT(nums) 61 | return res 62 | } 63 | ``` 64 | ## 47.全排列 II 65 | 1. 回溯 66 | ```go 67 | func permuteUnique(nums []int) [][]int { 68 | sort.Ints(nums) 69 | var res [][]int 70 | var tmpS []int 71 | lenN := len(nums) 72 | usedS := make([]int, lenN) 73 | var BT func(nums []int) 74 | BT = func(nums []int) { 75 | fmt.Println("tmpS:", tmpS, " usedS: ", usedS) 76 | if len(tmpS) == lenN { 77 | copyS := make([]int, len(tmpS)) 78 | copy(copyS, tmpS) 79 | res = append(res, copyS) 80 | return 81 | } 82 | for i := 0; i < lenN; { 83 | fmt.Println(i) 84 | if usedS[i] == 1 { 85 | i++ 86 | continue 87 | } 88 | tmpS = append(tmpS, nums[i]) 89 | usedS[i] = 1 90 | BT(nums) 91 | usedS[i] = 0 92 | tmpS = tmpS[:len(tmpS)-1] 93 | i++ 94 | for i < lenN { 95 | fmt.Println(i) 96 | if nums[i] == nums[i-1] { 97 | i++ 98 | } else { 99 | break 100 | } 101 | } 102 | } 103 | } 104 | BT(nums) 105 | return res 106 | } 107 | ``` -------------------------------------------------------------------------------- /day0517/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func findSubsequences(nums []int) [][]int { 9 | var res [][]int 10 | numsL := len(nums) 11 | var tmpS []int 12 | var BT func(nums []int, idx int) 13 | 14 | BT = func(nums []int, idx int) { 15 | usedS := make([]int, 201) 16 | for i := idx; i < numsL; i++ { 17 | if len(tmpS) > 0 && nums[i] < tmpS[len(tmpS)-1] || usedS[nums[i]+100] == 1 { 18 | continue 19 | } 20 | tmpS = append(tmpS, nums[i]) 21 | if len(tmpS) > 1 { 22 | copyS := make([]int, len(tmpS)) 23 | copy(copyS, tmpS) 24 | res = append(res, copyS) 25 | } 26 | BT(nums, i+1) 27 | tmpS = tmpS[:len(tmpS)-1] 28 | usedS[nums[i]+100] = 1 29 | } 30 | } 31 | BT(nums, 0) 32 | return res 33 | } 34 | 35 | /* 36 | [1,2,3,4,5,6] 37 | */ 38 | 39 | func permute(nums []int) [][]int { 40 | var res [][]int 41 | var tmpS []int 42 | lenN := len(nums) 43 | usedS := make([]int, lenN) 44 | var BT func(nums []int) 45 | BT = func(nums []int) { 46 | if len(tmpS) == lenN { 47 | copyS := make([]int, len(tmpS)) 48 | copy(copyS, tmpS) 49 | res = append(res, copyS) 50 | return 51 | } 52 | for i := 0; i < lenN; i++ { 53 | if usedS[i] == 1 { 54 | continue 55 | } 56 | tmpS = append(tmpS, nums[i]) 57 | usedS[i] = 1 58 | BT(nums) 59 | usedS[i] = 0 60 | tmpS = tmpS[:len(tmpS)-1] 61 | } 62 | } 63 | BT(nums) 64 | return res 65 | } 66 | 67 | /* 68 | [1,1,1,2,2,2] 69 | */ 70 | func permuteUnique(nums []int) [][]int { 71 | sort.Ints(nums) 72 | var res [][]int 73 | var tmpS []int 74 | lenN := len(nums) 75 | usedS := make([]int, lenN) 76 | var BT func(nums []int) 77 | BT = func(nums []int) { 78 | fmt.Println("tmpS:", tmpS, " usedS: ", usedS) 79 | if len(tmpS) == lenN { 80 | copyS := make([]int, len(tmpS)) 81 | copy(copyS, tmpS) 82 | res = append(res, copyS) 83 | return 84 | } 85 | for i := 0; i < lenN; { 86 | fmt.Println(i) 87 | if usedS[i] == 1 { 88 | i++ 89 | continue 90 | } 91 | tmpS = append(tmpS, nums[i]) 92 | usedS[i] = 1 93 | BT(nums) 94 | usedS[i] = 0 95 | tmpS = tmpS[:len(tmpS)-1] 96 | i++ 97 | for i < lenN { 98 | fmt.Println(i) 99 | if nums[i] == nums[i-1] { 100 | i++ 101 | } else { 102 | break 103 | } 104 | } 105 | } 106 | } 107 | BT(nums) 108 | return res 109 | } 110 | -------------------------------------------------------------------------------- /day0519/Day31贪心算法part01.md: -------------------------------------------------------------------------------- 1 | # Day31贪心算法part01 2 | 3 | ## 455.分发饼干 4 | 1. 贪心 5 | ```go 6 | func findContentChildren(g []int, s []int) int { 7 | if len(g) == 0 || len(s) == 0 { 8 | return 0 9 | } 10 | sort.Ints(g) 11 | sort.Ints(s) 12 | lenS := len(s) 13 | max := s[lenS-1] 14 | fast := 0 15 | slow := 0 16 | 17 | for ; fast < len(g); fast++ { 18 | if g[fast] > max || slow >= lenS { 19 | break 20 | } 21 | for ; slow < len(s); slow++ { 22 | if s[slow] >= g[fast] { 23 | slow++ 24 | break 25 | } 26 | } 27 | } 28 | return fast 29 | } 30 | ``` 31 | 32 | ## 376. 摆动序列 33 | 1. 贪心 34 | ```go 35 | func wiggleMaxLength(nums []int) int { 36 | numsL := len(nums) 37 | if numsL <= 1 { 38 | return numsL 39 | } 40 | slow := 1 41 | res := 1 42 | flagN := true 43 | 44 | for ; slow < numsL; slow++ { 45 | if nums[slow] != nums[slow-1] { 46 | if nums[slow] > nums[slow-1] { 47 | flagN = true 48 | } else { 49 | flagN = false 50 | } 51 | res++ 52 | break 53 | } 54 | } 55 | if slow == numsL-1 { 56 | return res 57 | } 58 | for i := slow + 1; i < numsL; i++ { 59 | if flagN { 60 | if nums[i] < nums[i-1] { 61 | flagN = false 62 | res++ 63 | } 64 | } else { 65 | if nums[i] > nums[i-1] { 66 | flagN = true 67 | res++ 68 | } 69 | } 70 | } 71 | return res 72 | } 73 | ``` 74 | 75 | ## 53. 最大子序和 76 | 1. 贪心 77 | ```go 78 | func maxSubArray(nums []int) int { 79 | res := nums[0] 80 | for i := 1; i < len(nums); i++ { 81 | if nums[i]+nums[i-1] > nums[i] { 82 | nums[i] += nums[i-1] 83 | } 84 | if nums[i] > res { 85 | res = nums[i] 86 | } 87 | } 88 | return res 89 | } 90 | ``` -------------------------------------------------------------------------------- /day0520/Day32贪心算法part02.md: -------------------------------------------------------------------------------- 1 | # Day32贪心算法part02 2 | 3 | ## 122.买卖股票的最佳时机II 4 | 1. 贪心 5 | ```go 6 | func maxProfit(prices []int) int { 7 | pricesL := len(prices) 8 | if pricesL <= 1 { 9 | return 0 10 | } 11 | res := 0 12 | for i := 1; i < pricesL; i++ { 13 | if prices[i] > prices[i-1] { 14 | res += prices[i] - prices[i-1] 15 | } 16 | } 17 | return res 18 | } 19 | ``` 20 | 21 | ## 55. 跳跃游戏 22 | 1. 贪心 23 | ```go 24 | func canJump(nums []int) bool { 25 | cover := nums[0] 26 | for i := 1; i < len(nums); i++ { 27 | if cover < i { 28 | return false 29 | } 30 | if i+nums[i] > cover { 31 | cover = i + nums[i] 32 | } 33 | } 34 | return true 35 | } 36 | ``` 37 | 38 | ## 45.跳跃游戏II 39 | 1. 动态规划 40 | ```go 41 | func jumpDP(nums []int) int { 42 | numsL := len(nums) 43 | dp := make([]int, numsL) 44 | for i := 0; i < numsL; i++ { 45 | dp[i] = numsL 46 | } 47 | dp[numsL-1] = 0 48 | for i := numsL - 2; i >= 0; i-- { 49 | min := numsL 50 | for j := 0; j <= nums[i] && i+j <= (numsL-1); j++ { 51 | if 1+dp[i+j] < min { 52 | min = 1 + dp[i+j] 53 | } 54 | } 55 | dp[i] = min 56 | } 57 | return dp[0] 58 | } 59 | ``` 60 | 2. 贪心 61 | ```go 62 | func max(x, y int) int {if x > y {return x};return y} 63 | 64 | func jump(nums []int) int { 65 | numsL := len(nums) 66 | if numsL == 1 { 67 | return 0 68 | } 69 | res := 0 70 | cur := 0 71 | next := 0 72 | for i := 0; i < numsL-1; i++ { 73 | next = max(nums[i]+1, next) 74 | if i == cur { 75 | if next >= (numsL - 1) { 76 | res++ 77 | break 78 | } 79 | res++ 80 | cur = next 81 | } 82 | } 83 | return res 84 | } 85 | ``` -------------------------------------------------------------------------------- /day0520/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func maxProfit(prices []int) int { 6 | pricesL := len(prices) 7 | if pricesL <= 1 { 8 | return 0 9 | } 10 | res := 0 11 | for i := 1; i < pricesL; i++ { 12 | if prices[i] > prices[i-1] { 13 | res += prices[i] - prices[i-1] 14 | } 15 | } 16 | return res 17 | } 18 | 19 | func canJumpOld(nums []int) bool { 20 | numsL := len(nums) 21 | if numsL == 1 { 22 | return true 23 | } 24 | nums[numsL-1] = -1 25 | for i := numsL - 2; i >= 0; i-- { 26 | fmt.Println(nums, i) 27 | for j := 1; j <= nums[i] && (j+i) < numsL; j++ { 28 | if nums[j+i] == -1 { 29 | nums[i] = -1 30 | break 31 | } 32 | } 33 | } 34 | if nums[0] == -1 { 35 | return true 36 | } 37 | return false 38 | } 39 | 40 | func canJump(nums []int) bool { 41 | cover := nums[0] 42 | for i := 1; i < len(nums); i++ { 43 | if cover < i { 44 | return false 45 | } 46 | if i+nums[i] > cover { 47 | cover = i + nums[i] 48 | } 49 | } 50 | return true 51 | } 52 | 53 | func jumpDP(nums []int) int { 54 | numsL := len(nums) 55 | dp := make([]int, numsL) 56 | for i := 0; i < numsL; i++ { 57 | dp[i] = numsL 58 | } 59 | dp[numsL-1] = 0 60 | for i := numsL - 2; i >= 0; i-- { 61 | min := numsL 62 | for j := 0; j <= nums[i] && i+j <= (numsL-1); j++ { 63 | if 1+dp[i+j] < min { 64 | min = 1 + dp[i+j] 65 | } 66 | } 67 | dp[i] = min 68 | } 69 | return dp[0] 70 | } 71 | 72 | func max(x, y int) int { 73 | if x > y { 74 | return x 75 | } 76 | return y 77 | } 78 | 79 | func jump(nums []int) int { 80 | numsL := len(nums) 81 | if numsL == 1 { 82 | return 0 83 | } 84 | res := 0 85 | cur := 0 86 | next := 0 87 | for i := 0; i < numsL-1; i++ { 88 | next = max(nums[i]+1, next) 89 | if i == cur { 90 | if next >= (numsL - 1) { 91 | res++ 92 | break 93 | } 94 | res++ 95 | cur = next 96 | } 97 | } 98 | return res 99 | } 100 | -------------------------------------------------------------------------------- /day0522/Day34贪心算法part03.md: -------------------------------------------------------------------------------- 1 | # Day34贪心算法part03 2 | 3 | ## 1005.K次取反后最大化的数组和 4 | ```go 5 | func largestSumAfterKNegations(nums []int, k int) int { 6 | sort.Slice(nums, func(i, j int) bool { 7 | if nums[i] < 0 { 8 | if nums[j] < 0 { 9 | return -nums[i] < -nums[j] 10 | } else { 11 | return -nums[i] < nums[j] 12 | } 13 | } else if nums[j] < 0 { 14 | return nums[i] < -nums[j] 15 | } 16 | return nums[i] < nums[j] 17 | }) 18 | sum := 0 19 | for i := len(nums) - 1; i >= 0; i-- { 20 | if nums[i] < 0 && k > 0 { 21 | nums[i] = -nums[i] 22 | k-- 23 | } 24 | sum += nums[i] 25 | } 26 | fmt.Println(nums) 27 | if k > 0 { 28 | if k%2 != 0 { 29 | sum -= nums[0] * 2 30 | } 31 | } 32 | return sum 33 | 34 | } 35 | ``` 36 | 37 | ## 134. 加油站 38 | ```go 39 | /* 40 | gas = [1,2,3,4,5], 41 | cost = [3,4,5,1,2] 42 | [-2,-2,-2,3,3] 43 | [-1,-1,1] 44 | */ 45 | func canCompleteCircuit(gas []int, cost []int) int { 46 | start := 0 47 | rGas := 0 48 | sGas := 0 49 | for i := 0; i < len(gas); i++ { 50 | sGas += gas[i] - cost[i] 51 | rGas += gas[i] - cost[i] 52 | if rGas < 0 { 53 | start = i + 1 54 | rGas = 0 55 | } 56 | } 57 | if sGas < 0 { 58 | return -1 59 | } 60 | return start 61 | } 62 | ``` 63 | 64 | ## 135. 分发糖果 65 | ```go 66 | func candy(ratings []int) int { 67 | lenR := len(ratings) 68 | if lenR == 1 { 69 | return 1 70 | } 71 | candyS := make([]int, lenR) 72 | for i := 1; i < lenR; i++ { 73 | candyS[i] = 1 74 | } 75 | for i := 0; i < lenR; i++ { 76 | if ratings[i] > ratings[i-1] { 77 | candyS[i] = candyS[i-1] + 1 78 | } 79 | } 80 | /* 81 | 82 | */ 83 | //if candyS[lenR-1] == 0 { 84 | // candyS[lenR-1] = 1 85 | //} 86 | fmt.Println(candyS) 87 | sumC := candyS[lenR-1] 88 | for i := lenR - 2; i >= 0; i-- { 89 | if ratings[i] > ratings[i+1] { 90 | if candyS[i] < candyS[i+1]+1 { 91 | candyS[i] = candyS[i+1] + 1 92 | } 93 | } 94 | sumC += candyS[i] 95 | } 96 | return sumC 97 | } 98 | ``` -------------------------------------------------------------------------------- /day0522/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func largestSumAfterKNegations(nums []int, k int) int { 9 | sort.Slice(nums, func(i, j int) bool { 10 | if nums[i] < 0 { 11 | if nums[j] < 0 { 12 | return -nums[i] < -nums[j] 13 | } else { 14 | return -nums[i] < nums[j] 15 | } 16 | } else if nums[j] < 0 { 17 | return nums[i] < -nums[j] 18 | } 19 | return nums[i] < nums[j] 20 | }) 21 | sum := 0 22 | for i := len(nums) - 1; i >= 0; i-- { 23 | if nums[i] < 0 && k > 0 { 24 | nums[i] = -nums[i] 25 | k-- 26 | } 27 | sum += nums[i] 28 | } 29 | fmt.Println(nums) 30 | if k > 0 { 31 | if k%2 != 0 { 32 | sum -= nums[0] * 2 33 | } 34 | } 35 | return sum 36 | 37 | } 38 | 39 | /* 40 | gas = [1,2,3,4,5], 41 | cost = [3,4,5,1,2] 42 | [-2,-2,-2,3,3] 43 | [-1,-1,1] 44 | */ 45 | func canCompleteCircuit(gas []int, cost []int) int { 46 | start := 0 47 | rGas := 0 48 | sGas := 0 49 | for i := 0; i < len(gas); i++ { 50 | sGas += gas[i] - cost[i] 51 | rGas += gas[i] - cost[i] 52 | if rGas < 0 { 53 | start = i + 1 54 | rGas = 0 55 | } 56 | } 57 | if sGas < 0 { 58 | return -1 59 | } 60 | return start 61 | } 62 | 63 | func candy(ratings []int) int { 64 | lenR := len(ratings) 65 | if lenR == 1 { 66 | return 1 67 | } 68 | candyS := make([]int, lenR) 69 | for i := 1; i < lenR; i++ { 70 | candyS[i] = 1 71 | } 72 | for i := 0; i < lenR; i++ { 73 | if ratings[i] > ratings[i-1] { 74 | candyS[i] = candyS[i-1] + 1 75 | } 76 | } 77 | /* 78 | 79 | */ 80 | //if candyS[lenR-1] == 0 { 81 | // candyS[lenR-1] = 1 82 | //} 83 | fmt.Println(candyS) 84 | sumC := candyS[lenR-1] 85 | for i := lenR - 2; i >= 0; i-- { 86 | if ratings[i] > ratings[i+1] { 87 | if candyS[i] < candyS[i+1]+1 { 88 | candyS[i] = candyS[i+1] + 1 89 | } 90 | } 91 | sumC += candyS[i] 92 | } 93 | return sumC 94 | } 95 | -------------------------------------------------------------------------------- /day0523/Day35贪心算法part04.md: -------------------------------------------------------------------------------- 1 | # Day35贪心算法part04 2 | 3 | ## 860.柠檬水找零 4 | ```go 5 | func lemonadeChange(bills []int) bool { 6 | cashMap := map[int]int{5: 0, 10: 0, 20: 0} 7 | for i := 0; i < len(bills); i++ { 8 | if bills[i] == 5 { 9 | cashMap[5] += 1 10 | } else if bills[i] == 10 { 11 | if cashMap[5] == 0 { 12 | return false 13 | } else { 14 | cashMap[10] += 1 15 | cashMap[5] -= 1 16 | } 17 | } else { 18 | if cashMap[10] > 0 && cashMap[5] > 0 { 19 | cashMap[10] -= 1 20 | cashMap[5] -= 1 21 | } else if cashMap[5] > 2 { 22 | cashMap[5] -= 3 23 | } else { 24 | return false 25 | } 26 | } 27 | } 28 | return true 29 | } 30 | ``` 31 | ## 406.根据身高重建队列 32 | ```go 33 | func reconstructQueue(people [][]int) [][]int { 34 | sort.Slice(people, func(i, j int) bool { 35 | if people[i][0] > people[j][0] { 36 | return true 37 | } else if people[i][0] < people[j][0] { 38 | return false 39 | } else { 40 | if people[i][1] <= people[j][1] { 41 | return true 42 | } else { 43 | return false 44 | } 45 | } 46 | }) 47 | queue := make([][]int, 0) 48 | for i := 0; i < len(people); i++ { 49 | if people[i][1] == len(queue) { 50 | queue = append(queue, people[i]) 51 | } else { 52 | queue = append(queue[:people[i][1]], append([][]int{people[i]}, queue[people[i][1]:]...)...) 53 | } 54 | } 55 | return queue 56 | 57 | } 58 | ``` 59 | 60 | ## 452. 用最少数量的箭引爆气球 61 | ```go 62 | func findMinArrowShots(points [][]int) int { 63 | sort.Slice(points, func(i, j int) bool { 64 | if points[i][0] < points[j][0] { 65 | return true 66 | } else if points[i][0] > points[j][0] { 67 | return false 68 | } else { 69 | if points[i][1] < points[j][1] { 70 | return true 71 | } 72 | return false 73 | } 74 | }) 75 | //fmt.Println(points) 76 | idx := 0 77 | res := 1 78 | start := points[idx][0] 79 | limit := points[idx][1] 80 | for i := idx + 1; i < len(points); i++ { 81 | if points[i][1] < limit { 82 | limit = points[i][1] 83 | } 84 | start = points[i][0] 85 | if start > limit { 86 | res++ 87 | start = points[i][0] 88 | limit = points[i][1] 89 | } 90 | } 91 | return res 92 | } 93 | ``` -------------------------------------------------------------------------------- /day0524/Day36贪心算法part05.md: -------------------------------------------------------------------------------- 1 | # Day36贪心算法part05 2 | 3 | ## 435. 无重叠区间 4 | ```go 5 | func min(a, b int) int { 6 | if a < b { 7 | return a 8 | } 9 | return b 10 | } 11 | 12 | func eraseOverlapIntervals(intervals [][]int) int { 13 | if len(intervals) == 1 { 14 | return 0 15 | } 16 | sort.Slice(intervals, func(i, j int) bool { 17 | return intervals[i][0] < intervals[j][0] 18 | }) 19 | res := 0 20 | end := intervals[0][1] 21 | fmt.Println(intervals) 22 | for i := 1; i < len(intervals); i++ { 23 | if intervals[i][0] < end { 24 | end = min(end, intervals[i][1]) 25 | res++ 26 | } else { 27 | end = intervals[i][1] 28 | } 29 | } 30 | return res 31 | } 32 | ``` 33 | 34 | ## 763.划分字母区间 35 | ```go 36 | func partitionLabels(s string) []int { 37 | alS := [26]int{} 38 | for i := 0; i < len(s); i++ { 39 | alS[int(s[i]-'a')] = i 40 | } 41 | left, right := 0, 0 42 | res := make([]int, 0) 43 | for i := 0; i < len(s); i++ { 44 | if alS[int(s[i]-'a')] > right { 45 | right = alS[int(s[i]-'a')] 46 | } 47 | if i == right { 48 | res = append(res, right-left+1) 49 | left = i + 1 50 | } 51 | } 52 | return res 53 | } 54 | ``` 55 | 56 | ## 56. 合并区间 57 | ```go 58 | func merge(intervals [][]int) [][]int { 59 | if len(intervals) == 1 { 60 | return intervals 61 | } 62 | sort.Slice(intervals, func(i, j int) bool { 63 | return intervals[i][0] < intervals[j][0] 64 | }) 65 | res := make([][]int, 0) 66 | for i := 1; i < len(intervals); i++ { 67 | if intervals[i][0] <= intervals[i-1][1] { 68 | intervals[i][0] = intervals[i-1][0] 69 | if intervals[i-1][1] > intervals[i][1] { 70 | intervals[i][1] = intervals[i-1][1] 71 | } 72 | } else { 73 | res = append(res, intervals[i-1]) 74 | } 75 | } 76 | res = append(res, intervals[len(intervals)-1]) 77 | return res 78 | } 79 | ``` -------------------------------------------------------------------------------- /day0524/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func min(a, b int) int { 9 | if a < b { 10 | return a 11 | } 12 | return b 13 | } 14 | 15 | func eraseOverlapIntervals(intervals [][]int) int { 16 | if len(intervals) == 1 { 17 | return 0 18 | } 19 | sort.Slice(intervals, func(i, j int) bool { 20 | return intervals[i][0] < intervals[j][0] 21 | }) 22 | res := 0 23 | end := intervals[0][1] 24 | fmt.Println(intervals) 25 | for i := 1; i < len(intervals); i++ { 26 | if intervals[i][0] < end { 27 | end = min(end, intervals[i][1]) 28 | res++ 29 | } else { 30 | end = intervals[i][1] 31 | } 32 | } 33 | return res 34 | } 35 | 36 | func partitionLabels(s string) []int { 37 | alS := [26]int{} 38 | for i := 0; i < len(s); i++ { 39 | alS[int(s[i]-'a')] = i 40 | } 41 | left, right := 0, 0 42 | res := make([]int, 0) 43 | for i := 0; i < len(s); i++ { 44 | if alS[int(s[i]-'a')] > right { 45 | right = alS[int(s[i]-'a')] 46 | } 47 | if i == right { 48 | res = append(res, right-left+1) 49 | left = i + 1 50 | } 51 | } 52 | return res 53 | } 54 | func merge(intervals [][]int) [][]int { 55 | if len(intervals) == 1 { 56 | return intervals 57 | } 58 | sort.Slice(intervals, func(i, j int) bool { 59 | return intervals[i][0] < intervals[j][0] 60 | }) 61 | res := make([][]int, 0) 62 | for i := 1; i < len(intervals); i++ { 63 | if intervals[i][0] <= intervals[i-1][1] { 64 | intervals[i][0] = intervals[i-1][0] 65 | if intervals[i-1][1] > intervals[i][1] { 66 | intervals[i][1] = intervals[i-1][1] 67 | } 68 | } else { 69 | res = append(res, intervals[i-1]) 70 | } 71 | } 72 | res = append(res, intervals[len(intervals)-1]) 73 | return res 74 | } 75 | -------------------------------------------------------------------------------- /day0525/Day37贪心算法part06.md: -------------------------------------------------------------------------------- 1 | # Day37贪心算法part06 2 | 3 | ## 738.单调递增的数字 4 | ```go 5 | func monotoneIncreasingDigits(n int) int { 6 | if n < 10 { 7 | return n 8 | } 9 | numS := make([]int, 0) 10 | for n > 0 { 11 | numS = append([]int{n % 10}, numS...) 12 | n /= 10 13 | } 14 | 15 | idx := len(numS) 16 | for i := len(numS) - 2; i >= 0; i-- { 17 | if numS[i] > numS[i+1] { 18 | numS[i] -= 1 19 | for j := i + 1; j < idx; j++ { 20 | numS[j] = 9 21 | } 22 | idx = i + 1 23 | } 24 | } 25 | res := 0 26 | for i := 0; i < len(numS); i++ { 27 | res = res*10 + numS[i] 28 | } 29 | return res 30 | } 31 | ``` 32 | 33 | ## 968.监控二叉树 34 | ```go 35 | func minCameraCover(root *TreeNode) int { 36 | res := 0 37 | var dfs func(root *TreeNode) int 38 | dfs = func(root *TreeNode) int { 39 | if root == nil { 40 | return 2 41 | } 42 | left := dfs(root.Left) 43 | right := dfs(root.Right) 44 | if left == 0 || right == 0 { 45 | res++ 46 | return 1 47 | } else if left == 2 && right == 2 { 48 | return 0 49 | } else { 50 | return 2 51 | } 52 | } 53 | rootRes := dfs(root) 54 | if rootRes == 0 { 55 | return res + 1 56 | } 57 | return res 58 | 59 | } 60 | ``` -------------------------------------------------------------------------------- /day0525/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "Code_Random_Thoughts/mypkg" 5 | "fmt" 6 | "strconv" 7 | ) 8 | 9 | /* 10 | 2335 11 | */ 12 | func monotoneIncreasingDigits(n int) int { 13 | if n < 10 { 14 | return n 15 | } 16 | numS := make([]int, 0) 17 | for n > 0 { 18 | numS = append([]int{n % 10}, numS...) 19 | n /= 10 20 | } 21 | 22 | idx := len(numS) 23 | for i := len(numS) - 2; i >= 0; i-- { 24 | if numS[i] > numS[i+1] { 25 | numS[i] -= 1 26 | for j := i + 1; j < idx; j++ { 27 | numS[j] = 9 28 | } 29 | idx = i + 1 30 | } 31 | } 32 | res := 0 33 | for i := 0; i < len(numS); i++ { 34 | res = res*10 + numS[i] 35 | } 36 | return res 37 | } 38 | 39 | func minCameraCover(root *TreeNode) int { 40 | res := 0 41 | var dfs func(root *TreeNode) int 42 | dfs = func(root *TreeNode) int { 43 | if root == nil { 44 | return 2 45 | } 46 | left := dfs(root.Left) 47 | right := dfs(root.Right) 48 | if left == 0 || right == 0 { 49 | res++ 50 | return 1 51 | } else if left == 2 && right == 2 { 52 | return 0 53 | } else { 54 | return 2 55 | } 56 | } 57 | rootRes := dfs(root) 58 | if rootRes == 0 { 59 | return res + 1 60 | } 61 | return res 62 | 63 | } 64 | 65 | func main() { 66 | num := 1234567890 67 | fmt.Println(num) 68 | strNum := strconv.Itoa(num) // 将整数转换为字符串 69 | chars := []byte(strNum) // 将字符串转换为字符切片 70 | for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 { 71 | chars[i], chars[j] = chars[j], chars[i] 72 | } 73 | reverseStrNum := string(chars) // 反转字符切片并转换为字符串 74 | for _, ch := range reverseStrNum { 75 | fmt.Printf("%c\n", ch) // 逐个字符地输出反转后的字符串 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /day0526/Day38动态规划part01.md: -------------------------------------------------------------------------------- 1 | # Day38动态规划part01 2 | 3 | ## 509. 斐波那契数 4 | ```go 5 | func fib(n int) int { 6 | if n < 2 { 7 | return n 8 | } 9 | dp := make([]int, n+1) 10 | dp[0], dp[1] = 0, 1 11 | for i := 2; i < len(dp); i++ { 12 | dp[i] = dp[i-1] + dp[i-2] 13 | } 14 | return dp[n] 15 | } 16 | ``` 17 | ## 70. 爬楼梯 18 | ```go 19 | func climbStairs(n int) int { 20 | if n < 3 { 21 | return n 22 | } 23 | dp := make([]int, n+1) 24 | dp[len(dp)-1] = 0 25 | dp[len(dp)-2] = 1 26 | for i := len(dp) - 3; i >= 0; i-- { 27 | dp[i] = dp[i+1] + dp[i+2] 28 | fmt.Println(dp) 29 | } 30 | return dp[0] 31 | } 32 | ``` 33 | ## 746. 使用最小花费爬楼梯 34 | ```go 35 | func min(m, n int) int { 36 | if m < n { 37 | return m 38 | } 39 | return n 40 | } 41 | 42 | func minCostClimbingStairs(cost []int) int { 43 | lenC := len(cost) 44 | if lenC == 2 { 45 | return min(cost[0], cost[1]) 46 | } 47 | dp := make([]int, lenC+1) 48 | dp[0], dp[1] = 0, 0 49 | for i := 2; i <= lenC; i++ { 50 | dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]) 51 | fmt.Println(dp) 52 | } 53 | return dp[lenC] 54 | } 55 | ``` -------------------------------------------------------------------------------- /day0526/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func fib(n int) int { 6 | if n < 2 { 7 | return n 8 | } 9 | dp := make([]int, n+1) 10 | dp[0], dp[1] = 0, 1 11 | for i := 2; i < len(dp); i++ { 12 | dp[i] = dp[i-1] + dp[i-2] 13 | } 14 | return dp[n] 15 | } 16 | 17 | func climbStairs(n int) int { 18 | if n < 3 { 19 | return n 20 | } 21 | dp := make([]int, n+1) 22 | dp[len(dp)-1] = 0 23 | dp[len(dp)-2] = 1 24 | for i := len(dp) - 3; i >= 0; i-- { 25 | dp[i] = dp[i+1] + dp[i+2] 26 | fmt.Println(dp) 27 | } 28 | return dp[0] 29 | } 30 | 31 | func min(m, n int) int { 32 | if m < n { 33 | return m 34 | } 35 | return n 36 | } 37 | 38 | func minCostClimbingStairs(cost []int) int { 39 | lenC := len(cost) 40 | if lenC == 2 { 41 | return min(cost[0], cost[1]) 42 | } 43 | dp := make([]int, lenC+1) 44 | dp[0], dp[1] = 0, 0 45 | for i := 2; i <= lenC; i++ { 46 | dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]) 47 | fmt.Println(dp) 48 | } 49 | return dp[lenC] 50 | } 51 | -------------------------------------------------------------------------------- /day0527/Day39动态算法part02.md: -------------------------------------------------------------------------------- 1 | # Day39动态算法part02 2 | 3 | ## 62.不同路径 4 | ```go 5 | func uniquePaths(m int, n int) int { 6 | //if m == 1 && n == 1 { 7 | // return 1 8 | //} 9 | dp := make([][]int, m) 10 | for i := 0; i < m; i++ { 11 | tmpS := make([]int, n) 12 | dp[i] = tmpS 13 | //dp[i] = append(dp[i], tmpS...) 14 | } 15 | dp[m-1][n-1] = 1 16 | for i := m - 1; i >= 0; i-- { 17 | for j := n - 1; j >= 0; j-- { 18 | if i == m-1 && j == n-1 { 19 | continue 20 | } 21 | if i == m-1 { 22 | dp[i][j] += dp[i][j+1] 23 | } else if j == n-1 { 24 | dp[i][j] += dp[i+1][j] 25 | } else { 26 | dp[i][j] += dp[i+1][j] + dp[i][j+1] 27 | } 28 | } 29 | } 30 | return dp[0][0] 31 | } 32 | ``` 33 | 34 | ## 63. 不同路径 II 35 | ```go 36 | func uniquePathsWithObstacles(obstacleGrid [][]int) int { 37 | m := len(obstacleGrid) 38 | n := len(obstacleGrid[0]) 39 | dp := make([][]int, m) 40 | for i := 0; i < m; i++ { 41 | dp[i] = make([]int, n) 42 | } 43 | for i := 0; i < m; i++ { 44 | if obstacleGrid[i][0] == 1 { 45 | break 46 | } 47 | dp[i][0] = 1 48 | } 49 | for j := 0; j < n; j++ { 50 | if obstacleGrid[0][j] == 1 { 51 | break 52 | } 53 | dp[0][j] = 1 54 | } 55 | tmpM := 0 56 | tmpN := 0 57 | for i := 1; i < m; i++ { 58 | for j := 1; j < n; j++ { 59 | if obstacleGrid[i][j] == 1 { 60 | continue 61 | } 62 | tmpM, tmpN = 0, 0 63 | fmt.Println("i:", i, " j:", j, "\n", dp) 64 | if obstacleGrid[i-1][j] != 1 { 65 | tmpM = dp[i-1][j] 66 | } 67 | if obstacleGrid[i][j-1] != 1 { 68 | tmpN = dp[i][j-1] 69 | } 70 | dp[i][j] = tmpM + tmpN 71 | } 72 | } 73 | return dp[m-1][n-1] 74 | } 75 | ``` -------------------------------------------------------------------------------- /day0527/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func uniquePaths(m int, n int) int { 6 | //if m == 1 && n == 1 { 7 | // return 1 8 | //} 9 | dp := make([][]int, m) 10 | for i := 0; i < m; i++ { 11 | tmpS := make([]int, n) 12 | dp[i] = tmpS 13 | //dp[i] = append(dp[i], tmpS...) 14 | } 15 | dp[m-1][n-1] = 1 16 | for i := m - 1; i >= 0; i-- { 17 | for j := n - 1; j >= 0; j-- { 18 | if i == m-1 && j == n-1 { 19 | continue 20 | } 21 | if i == m-1 { 22 | dp[i][j] += dp[i][j+1] 23 | } else if j == n-1 { 24 | dp[i][j] += dp[i+1][j] 25 | } else { 26 | dp[i][j] += dp[i+1][j] + dp[i][j+1] 27 | } 28 | } 29 | } 30 | return dp[0][0] 31 | } 32 | 33 | func uniquePathsWithObstacles(obstacleGrid [][]int) int { 34 | m := len(obstacleGrid) 35 | n := len(obstacleGrid[0]) 36 | dp := make([][]int, m) 37 | for i := 0; i < m; i++ { 38 | dp[i] = make([]int, n) 39 | } 40 | for i := 0; i < m; i++ { 41 | if obstacleGrid[i][0] == 1 { 42 | break 43 | } 44 | dp[i][0] = 1 45 | } 46 | for j := 0; j < n; j++ { 47 | if obstacleGrid[0][j] == 1 { 48 | break 49 | } 50 | dp[0][j] = 1 51 | } 52 | tmpM := 0 53 | tmpN := 0 54 | for i := 1; i < m; i++ { 55 | for j := 1; j < n; j++ { 56 | if obstacleGrid[i][j] == 1 { 57 | continue 58 | } 59 | tmpM, tmpN = 0, 0 60 | fmt.Println("i:", i, " j:", j, "\n", dp) 61 | if obstacleGrid[i-1][j] != 1 { 62 | tmpM = dp[i-1][j] 63 | } 64 | if obstacleGrid[i][j-1] != 1 { 65 | tmpN = dp[i][j-1] 66 | } 67 | dp[i][j] = tmpM + tmpN 68 | } 69 | } 70 | return dp[m-1][n-1] 71 | } 72 | -------------------------------------------------------------------------------- /day0529/Day41动态算法part03.md: -------------------------------------------------------------------------------- 1 | # Day41动态规划part03 2 | 3 | ## 343. 整数拆分 4 | ```go 5 | func max(m, n int) int { 6 | if m > n { 7 | return m 8 | } 9 | return n 10 | } 11 | 12 | func integerBreak(n int) int { 13 | if n <= 2 { 14 | return 1 15 | } 16 | dp := make([]int, n+1) 17 | dp[2] = 1 18 | for i := 0; i <= n; i++ { 19 | for j := 0; j < i/2; j++ { 20 | dp[i] = max(dp[i], max(j*(i-j), j*dp[i-j])) 21 | } 22 | } 23 | return dp[n] 24 | } 25 | ``` 26 | 27 | ## 96.不同的二叉搜索树 28 | ```go 29 | func numTrees(n int) int { 30 | dp := make([]int, n+1) 31 | dp[0] = 1 32 | for i := 0; i <= n; i++ { 33 | for j := 1; j <= i; j++ { 34 | dp[i] += dp[j-1] * dp[i-j] 35 | } 36 | } 37 | return dp[n] 38 | } 39 | ``` -------------------------------------------------------------------------------- /day0529/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func max(m, n int) int { 4 | if m > n { 5 | return m 6 | } 7 | return n 8 | } 9 | 10 | func integerBreak(n int) int { 11 | if n <= 2 { 12 | return 1 13 | } 14 | dp := make([]int, n+1) 15 | dp[2] = 1 16 | for i := 0; i <= n; i++ { 17 | for j := 0; j < i/2; j++ { 18 | dp[i] = max(dp[i], max(j*(i-j), j*dp[i-j])) 19 | } 20 | } 21 | return dp[n] 22 | } 23 | 24 | func numTrees(n int) int { 25 | dp := make([]int, n+1) 26 | dp[0] = 1 27 | for i := 0; i <= n; i++ { 28 | for j := 1; j <= i; j++ { 29 | dp[i] += dp[j-1] * dp[i-j] 30 | } 31 | } 32 | return dp[n] 33 | } 34 | -------------------------------------------------------------------------------- /day0530/Day42动态算法part04.md: -------------------------------------------------------------------------------- 1 | # Day42动态算法part04 2 | 3 | ## 01背包问题 二维 4 | ```go 5 | func test2WeiBagProblem1(weight, value []int, bagweight int) int { 6 | // 定义dp数组 7 | dp := make([][]int, len(weight)) 8 | for i, _ := range dp { 9 | dp[i] = make([]int, bagweight+1) 10 | } 11 | // 初始化 12 | for j := bagweight; j >= weight[0]; j-- { 13 | dp[0][j] = dp[0][j-weight[0]] + value[0] 14 | } 15 | // 递推公式 16 | for i := 1; i < len(weight); i++ { 17 | //正序,也可以倒序 18 | for j := 0; j <= bagweight; j++ { 19 | if j < weight[i] { 20 | dp[i][j] = dp[i-1][j] 21 | } else { 22 | dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]) 23 | } 24 | } 25 | } 26 | return dp[len(weight)-1][bagweight] 27 | } 28 | ``` 29 | 30 | ## 01背包问题 一维 31 | ```go 32 | func test1WeiBagProblem(weight, value []int, bagWeight int) int { 33 | // 定义 and 初始化 34 | dp := make([]int, bagWeight+1) 35 | // 递推顺序 36 | for i := 0; i < len(weight); i++ { 37 | // 这里必须倒序,区别二维,因为二维dp保存了i的状态 38 | for j := bagWeight; j >= weight[i]; j-- { 39 | // 递推公式 40 | dp[j] = max(dp[j], dp[j-weight[i]]+value[i]) 41 | } 42 | } 43 | //fmt.Println(dp) 44 | return dp[bagWeight] 45 | } 46 | ``` 47 | 48 | # 416. 分割等和子集 49 | ```go 50 | func canPartition(nums []int) bool { 51 | sum := 0 52 | numsL := len(nums) 53 | if numsL == 1 { 54 | return false 55 | } 56 | for i := 0; i < numsL; i++ { 57 | sum += nums[i] 58 | } 59 | if sum%2 != 0 { 60 | return false 61 | } else { 62 | sum /= 2 63 | } 64 | dp := make([]int, sum+1) 65 | for i := 0; i < numsL; i++ { 66 | for j := sum; j >= nums[i]; j-- { 67 | dp[j] = max(dp[j], dp[j-nums[i]]+nums[i]) 68 | } 69 | } 70 | if dp[sum] == sum { 71 | return true 72 | } 73 | return false 74 | } 75 | ``` -------------------------------------------------------------------------------- /day0530/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func test2WeiBagProblem1(weight, value []int, bagweight int) int { 4 | // 定义dp数组 5 | dp := make([][]int, len(weight)) 6 | for i, _ := range dp { 7 | dp[i] = make([]int, bagweight+1) 8 | } 9 | // 初始化 10 | for j := bagweight; j >= weight[0]; j-- { 11 | dp[0][j] = dp[0][j-weight[0]] + value[0] 12 | } 13 | // 递推公式 14 | for i := 1; i < len(weight); i++ { 15 | //正序,也可以倒序 16 | for j := 0; j <= bagweight; j++ { 17 | if j < weight[i] { 18 | dp[i][j] = dp[i-1][j] 19 | } else { 20 | dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]) 21 | } 22 | } 23 | } 24 | return dp[len(weight)-1][bagweight] 25 | } 26 | 27 | func max(a, b int) int { 28 | if a > b { 29 | return a 30 | } 31 | return b 32 | } 33 | func test1WeiBagProblem(weight, value []int, bagWeight int) int { 34 | // 定义 and 初始化 35 | dp := make([]int, bagWeight+1) 36 | // 递推顺序 37 | for i := 0; i < len(weight); i++ { 38 | // 这里必须倒序,区别二维,因为二维dp保存了i的状态 39 | for j := bagWeight; j >= weight[i]; j-- { 40 | // 递推公式 41 | dp[j] = max(dp[j], dp[j-weight[i]]+value[i]) 42 | } 43 | } 44 | //fmt.Println(dp) 45 | return dp[bagWeight] 46 | } 47 | 48 | func bagProblem(weight, value []int, bagWeight int) int { 49 | dp := make([]int, bagWeight+1) 50 | for i := 0; i < len(weight); i++ { 51 | for j := bagWeight; j >= weight[i]; j-- { 52 | dp[j] = max(dp[j], dp[j-weight[i]]+value[i]) 53 | } 54 | } 55 | return dp[bagWeight] 56 | } 57 | 58 | func canPartition(nums []int) bool { 59 | sum := 0 60 | numsL := len(nums) 61 | if numsL == 1 { 62 | return false 63 | } 64 | for i := 0; i < numsL; i++ { 65 | sum += nums[i] 66 | } 67 | if sum%2 != 0 { 68 | return false 69 | } else { 70 | sum /= 2 71 | } 72 | dp := make([]int, sum+1) 73 | for i := 0; i < numsL; i++ { 74 | for j := sum; j >= nums[i]; j-- { 75 | dp[j] = max(dp[j], dp[j-nums[i]]+nums[i]) 76 | } 77 | } 78 | if dp[sum] == sum { 79 | return true 80 | } 81 | return false 82 | } 83 | 84 | func main() { 85 | weight := []int{1, 3, 4} 86 | value := []int{15, 20, 30} 87 | test2WeiBagProblem1(weight, value, 4) 88 | } 89 | -------------------------------------------------------------------------------- /day0531/Day43动态算法part05.md: -------------------------------------------------------------------------------- 1 | # Day43动态算法part05 2 | 3 | # 1049. 最后一块石头的重量 II 4 | ```go 5 | func max(m, n int) int { 6 | if m > n { 7 | return m 8 | } 9 | return n 10 | } 11 | 12 | func lastStoneWeightII(stones []int) int { 13 | sum := 0 14 | sL := len(stones) 15 | if sL == 1 { 16 | return stones[0] 17 | } 18 | for i := 0; i < sL; i++ { 19 | sum += stones[i] 20 | } 21 | bag := sum / 2 22 | dp := make([]int, bag+1) 23 | for i := 0; i < sL; i++ { 24 | for j := bag; j >= stones[i]; j-- { 25 | dp[j] = max(dp[j], dp[j-stones[i]]+stones[i]) 26 | } 27 | } 28 | return sum - dp[bag]*2 29 | } 30 | ``` 31 | # 494. 目标和 32 | ```go 33 | func abs(x int) int { 34 | return int(math.Abs(float64(x))) 35 | } 36 | func findTargetSumWays(nums []int, target int) int { 37 | sum := 0 38 | numsL := len(nums) 39 | for i := 0; i < numsL; i++ { 40 | sum += nums[i] 41 | } 42 | if ((sum+target)%2 != 0) || (sum < abs(target)) { 43 | return 0 44 | } 45 | sum = (target + sum) / 2 46 | dp := make([]int, sum+1) 47 | dp[0] = 1 48 | for i := 0; i < numsL; i++ { 49 | for j := sum; j >= nums[i]; j-- { 50 | dp[j] += dp[j-nums[i]] 51 | fmt.Println("i:", i, " j:", j, " ", dp) 52 | } 53 | } 54 | return dp[sum] 55 | } 56 | ``` 57 | # 474.一和零 58 | ```go 59 | func getNum(str string) (m, n int) { 60 | for i := 0; i < len(str); i++ { 61 | if str[i] == '0' { 62 | m++ 63 | } else { 64 | n++ 65 | } 66 | } 67 | return 68 | } 69 | func findMaxForm(strs []string, m int, n int) int { 70 | strS := make([][2]int, len(strs)) 71 | for i := 0; i < len(strS); i++ { 72 | strS[i][0], strS[i][1] = getNum(strs[i]) 73 | } 74 | fmt.Println(strS) 75 | dp := make([][]int, m+1) 76 | for i, _ := range dp { 77 | dp[i] = make([]int, n+1) 78 | } 79 | for i := 0; i < len(strS); i++ { 80 | for j := m; j >= strS[i][0]; j-- { 81 | for k := n; k >= strS[i][1]; k-- { 82 | dp[j][k] = max(dp[j][k], dp[j-strS[i][0]][k-strS[i][1]]+1) 83 | } 84 | } 85 | } 86 | return dp[m][n] 87 | } 88 | ``` -------------------------------------------------------------------------------- /day0531/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func max(m, n int) int { 9 | if m > n { 10 | return m 11 | } 12 | return n 13 | } 14 | 15 | func lastStoneWeightII(stones []int) int { 16 | sum := 0 17 | sL := len(stones) 18 | if sL == 1 { 19 | return stones[0] 20 | } 21 | for i := 0; i < sL; i++ { 22 | sum += stones[i] 23 | } 24 | bag := sum / 2 25 | dp := make([]int, bag+1) 26 | for i := 0; i < sL; i++ { 27 | for j := bag; j >= stones[i]; j-- { 28 | dp[j] = max(dp[j], dp[j-stones[i]]+stones[i]) 29 | } 30 | } 31 | return sum - dp[bag]*2 32 | } 33 | func abs(x int) int { 34 | return int(math.Abs(float64(x))) 35 | } 36 | func findTargetSumWays(nums []int, target int) int { 37 | sum := 0 38 | numsL := len(nums) 39 | for i := 0; i < numsL; i++ { 40 | sum += nums[i] 41 | } 42 | if ((sum+target)%2 != 0) || (sum < abs(target)) { 43 | return 0 44 | } 45 | sum = (target + sum) / 2 46 | dp := make([]int, sum+1) 47 | dp[0] = 1 48 | for i := 0; i < numsL; i++ { 49 | for j := sum; j >= nums[i]; j-- { 50 | dp[j] += dp[j-nums[i]] 51 | fmt.Println("i:", i, " j:", j, " ", dp) 52 | } 53 | } 54 | return dp[sum] 55 | } 56 | 57 | func getNum(str string) (m, n int) { 58 | for i := 0; i < len(str); i++ { 59 | if str[i] == '0' { 60 | m++ 61 | } else { 62 | n++ 63 | } 64 | } 65 | return 66 | } 67 | func findMaxForm(strs []string, m int, n int) int { 68 | strS := make([][2]int, len(strs)) 69 | for i := 0; i < len(strS); i++ { 70 | strS[i][0], strS[i][1] = getNum(strs[i]) 71 | } 72 | fmt.Println(strS) 73 | dp := make([][]int, m+1) 74 | for i, _ := range dp { 75 | dp[i] = make([]int, n+1) 76 | } 77 | for i := 0; i < len(strS); i++ { 78 | for j := m; j >= strS[i][0]; j-- { 79 | for k := n; k >= strS[i][1]; k-- { 80 | dp[j][k] = max(dp[j][k], dp[j-strS[i][0]][k-strS[i][1]]+1) 81 | } 82 | } 83 | } 84 | return dp[m][n] 85 | } 86 | -------------------------------------------------------------------------------- /day0601/Day44动态算法part06.md: -------------------------------------------------------------------------------- 1 | # Day44动态算法part06 2 | 3 | # 完全背包 4 | ```go 5 | package main 6 | 7 | import "fmt" 8 | 9 | // testCompletePack1 先遍历物品, 在遍历背包 10 | func testCompletePack1(weight, value []int, bagWeight int) int { 11 | // 定义dp数组 和初始化 12 | dp := make([]int, bagWeight+1) 13 | // 遍历顺序 14 | for i := 0; i < len(weight); i++ { 15 | // 正序会多次添加 value[i] 16 | for j := weight[i]; j <= bagWeight; j++ { 17 | // 推导公式 18 | dp[j] = max(dp[j], dp[j-weight[i]]+value[i]) 19 | // debug 20 | //fmt.Println(dp) 21 | } 22 | } 23 | return dp[bagWeight] 24 | } 25 | 26 | // testCompletePack2 先遍历背包, 在遍历物品 27 | func testCompletePack2(weight, value []int, bagWeight int) int { 28 | // 定义dp数组 和初始化 29 | dp := make([]int, bagWeight+1) 30 | // 遍历顺序 31 | // j从0 开始 32 | for j := 0; j <= bagWeight; j++ { 33 | for i := 0; i < len(weight); i++ { 34 | if j >= weight[i] { 35 | // 推导公式 36 | dp[j] = max(dp[j], dp[j-weight[i]]+value[i]) 37 | } 38 | // debug 39 | //fmt.Println(dp) 40 | } 41 | } 42 | return dp[bagWeight] 43 | } 44 | 45 | func max(a, b int) int { 46 | if a > b { 47 | return a 48 | } 49 | return b 50 | } 51 | 52 | func main() { 53 | weight := []int{1, 3, 4} 54 | price := []int{15, 20, 30} 55 | fmt.Println(testCompletePack1(weight, price, 4)) 56 | fmt.Println(testCompletePack2(weight, price, 4)) 57 | } 58 | ``` 59 | 60 | ## 518. 零钱兑换 II 61 | ```go 62 | func change(amount int, coins []int) int { 63 | dp := make([]int, amount+1) 64 | dp[0] = 1 65 | for i := 0; i < len(coins); i++ { 66 | for j := coins[i]; j <= amount; j++ { 67 | dp[j] += dp[j-coins[i]] 68 | } 69 | } 70 | return dp[amount] 71 | } 72 | ``` 73 | ## 377. 组合总和 Ⅳ 74 | ```go 75 | func combinationSum4(nums []int, target int) int { 76 | dp := make([]int, target+1) 77 | dp[0] = 1 78 | for i := 0; i <= target; i++ { 79 | for j := 0; j < len(nums); j++ { 80 | if nums[j] <= i { 81 | dp[i] += dp[i-nums[j]] 82 | } 83 | } 84 | } 85 | return dp[target] 86 | } 87 | ``` -------------------------------------------------------------------------------- /day0601/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // testCompletePack1 先遍历物品, 在遍历背包 6 | func testCompletePack1(weight, value []int, bagWeight int) int { 7 | // 定义dp数组 和初始化 8 | dp := make([]int, bagWeight+1) 9 | // 遍历顺序 10 | for i := 0; i < len(weight); i++ { 11 | // 正序会多次添加 value[i] 12 | for j := weight[i]; j <= bagWeight; j++ { 13 | // 推导公式 14 | dp[j] = max(dp[j], dp[j-weight[i]]+value[i]) 15 | // debug 16 | //fmt.Println(dp) 17 | } 18 | } 19 | return dp[bagWeight] 20 | } 21 | 22 | // testCompletePack2 先遍历背包, 在遍历物品 23 | func testCompletePack2(weight, value []int, bagWeight int) int { 24 | // 定义dp数组 和初始化 25 | dp := make([]int, bagWeight+1) 26 | // 遍历顺序 27 | // j从0 开始 28 | for j := 0; j <= bagWeight; j++ { 29 | for i := 0; i < len(weight); i++ { 30 | if j >= weight[i] { 31 | // 推导公式 32 | dp[j] = max(dp[j], dp[j-weight[i]]+value[i]) 33 | } 34 | // debug 35 | //fmt.Println(dp) 36 | } 37 | } 38 | return dp[bagWeight] 39 | } 40 | 41 | func max(a, b int) int { 42 | if a > b { 43 | return a 44 | } 45 | return b 46 | } 47 | 48 | func change(amount int, coins []int) int { 49 | dp := make([]int, amount+1) 50 | dp[0] = 1 51 | for i := 0; i < len(coins); i++ { 52 | for j := coins[i]; j <= amount; j++ { 53 | dp[j] += dp[j-coins[i]] 54 | } 55 | } 56 | return dp[amount] 57 | } 58 | 59 | func combinationSum4(nums []int, target int) int { 60 | dp := make([]int, target+1) 61 | dp[0] = 1 62 | for i := 0; i <= target; i++ { 63 | for j := 0; j < len(nums); j++ { 64 | if nums[j] <= i { 65 | dp[i] += dp[i-nums[j]] 66 | } 67 | } 68 | } 69 | return dp[target] 70 | } 71 | 72 | func main() { 73 | weight := []int{1, 3, 4} 74 | price := []int{15, 20, 30} 75 | fmt.Println(testCompletePack1(weight, price, 4)) 76 | fmt.Println(testCompletePack2(weight, price, 4)) 77 | } 78 | -------------------------------------------------------------------------------- /day0602/Day45动态算法part07.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part07 2 | ## 70. 爬楼梯 (进阶) 3 | ```go 4 | func climbStairs(n int) int { 5 | dp := make([]int, n+1) 6 | dp[0] = 1 7 | for i := 1; i <= n; i++ { 8 | for j := 1; j <= 2; j++ { 9 | if i-j >= 0 { 10 | dp[i] += dp[i-j] 11 | } 12 | } 13 | } 14 | return dp[n] 15 | } 16 | ``` 17 | ## 322. 零钱兑换 18 | ```go 19 | func coinChange(coins []int, amount int) int { 20 | if amount == 0 { 21 | return 0 22 | } 23 | dp := make([]int, amount+1) 24 | dp[0] = 0 25 | for i := 1; i < len(dp); i++ { 26 | dp[i] = amount + 1 27 | } 28 | for i := 0; i < len(coins); i++ { 29 | for j := coins[i]; j <= amount; j++ { 30 | dp[j] = min(dp[j], dp[j-coins[i]]+1) 31 | } 32 | } 33 | if dp[amount] == amount+1 { 34 | return -1 35 | } else { 36 | return dp[amount] 37 | } 38 | } 39 | ``` 40 | ## 279.完全平方数 41 | ```go 42 | func numSquares(n int) int { 43 | numS := make([]int, 101) 44 | for i := 0; i < len(numS); i++ { 45 | numS[i] = i * i 46 | } 47 | dp := make([]int, n+1) 48 | dp[0] = 0 49 | for i := 1; i < len(dp); i++ { 50 | dp[i] = n + 1 51 | } 52 | for i := 1; i < len(numS); i++ { 53 | for j := numS[i]; j <= n; j++ { 54 | dp[j] = min(dp[j], dp[j-numS[i]]+1) 55 | } 56 | } 57 | return dp[n] 58 | } 59 | ``` -------------------------------------------------------------------------------- /day0602/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func climbStairs(n int) int { 4 | dp := make([]int, n+1) 5 | dp[0] = 1 6 | for i := 1; i <= n; i++ { 7 | for j := 1; j <= 2; j++ { 8 | if i-j >= 0 { 9 | dp[i] += dp[i-j] 10 | } 11 | } 12 | } 13 | return dp[n] 14 | } 15 | 16 | func min(m, n int) int { 17 | if m < n { 18 | return m 19 | } 20 | return n 21 | } 22 | 23 | func coinChange(coins []int, amount int) int { 24 | if amount == 0 { 25 | return 0 26 | } 27 | dp := make([]int, amount+1) 28 | dp[0] = 0 29 | for i := 1; i < len(dp); i++ { 30 | dp[i] = amount + 1 31 | } 32 | for i := 0; i < len(coins); i++ { 33 | for j := coins[i]; j <= amount; j++ { 34 | dp[j] = min(dp[j], dp[j-coins[i]]+1) 35 | } 36 | } 37 | if dp[amount] == amount+1 { 38 | return -1 39 | } else { 40 | return dp[amount] 41 | } 42 | } 43 | 44 | func numSquares(n int) int { 45 | numS := make([]int, 101) 46 | for i := 0; i < len(numS); i++ { 47 | numS[i] = i * i 48 | } 49 | dp := make([]int, n+1) 50 | dp[0] = 0 51 | for i := 1; i < len(dp); i++ { 52 | dp[i] = n + 1 53 | } 54 | for i := 1; i < len(numS); i++ { 55 | for j := numS[i]; j <= n; j++ { 56 | dp[j] = min(dp[j], dp[j-numS[i]]+1) 57 | } 58 | } 59 | return dp[n] 60 | } 61 | -------------------------------------------------------------------------------- /day0603/Day46动态算法part08.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态算法part08 2 | ## 139.单词拆分 3 | ```go 4 | func wordBreak(s string, wordDict []string) bool { 5 | wordMap := make(map[string]struct{}) 6 | for i := 0; i < len(wordDict); i++ { 7 | wordMap[wordDict[i]] = struct{}{} 8 | } 9 | dp := make([]bool, len(s)+1) 10 | dp[0] = true 11 | for i := 0; i <= len(s); i++ { 12 | for j := 0; j <= i; j++ { 13 | if _, ok := wordMap[s[j:i]]; ok && dp[j] { 14 | dp[i] = true 15 | break 16 | } 17 | } 18 | } 19 | return dp[len(s)] 20 | } 21 | ``` 22 | ## 多重背包 23 | 转化为01背包问题求解 24 | ```go 25 | // 多重背包可以化解为 01 背包 26 | func multiplePack(weight, value, nums []int, bagWeight int) int { 27 | 28 | for i := 0; i < len(nums); i++ { 29 | for nums[i] > 1 { 30 | weight = append(weight, weight[i]) 31 | value = append(value, value[i]) 32 | nums[i]-- 33 | } 34 | } 35 | log.Println(weight) 36 | log.Println(value) 37 | 38 | res := make([]int, bagWeight+1) 39 | for i := 0; i < len(weight); i++ { 40 | for j := bagWeight; j >= weight[i]; j-- { 41 | res[j] = getMax(res[j], res[j-weight[i]]+value[i]) 42 | } 43 | log.Println(res) 44 | } 45 | 46 | return res[bagWeight] 47 | } 48 | ``` -------------------------------------------------------------------------------- /day0603/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func wordBreak(s string, wordDict []string) bool { 4 | wordMap := make(map[string]struct{}) 5 | for i := 0; i < len(wordDict); i++ { 6 | wordMap[wordDict[i]] = struct{}{} 7 | } 8 | dp := make([]bool, len(s)+1) 9 | dp[0] = true 10 | for i := 0; i <= len(s); i++ { 11 | for j := 0; j <= i; j++ { 12 | if _, ok := wordMap[s[j:i]]; ok && dp[j] { 13 | dp[i] = true 14 | break 15 | } 16 | } 17 | } 18 | return dp[len(s)] 19 | } 20 | -------------------------------------------------------------------------------- /day0605/Day48动态规划part09.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part09 2 | ## 198.打家劫舍 3 | ```go 4 | func max(m, n int) int { 5 | if m > n { 6 | return m 7 | } 8 | return n 9 | } 10 | 11 | /* 12 | 2 1 1 2 13 | 2 1 2 14 | */ 15 | func rob(nums []int) int { 16 | if len(nums) == 1 { 17 | return nums[0] 18 | } else if len(nums) == 2 { 19 | return max(nums[0], nums[1]) 20 | } 21 | dp := make([]int, len(nums)) 22 | dp[0], dp[1] = nums[0], max(nums[0], nums[1]) 23 | for i := 2; i < len(nums); i++ { 24 | dp[i] = max(dp[i-1], nums[i]+dp[i-2]) 25 | fmt.Println(dp) 26 | } 27 | return dp[len(nums)-1] 28 | } 29 | ``` 30 | ## 213.打家劫舍II 31 | ```go 32 | func robII(nums []int) int { 33 | if len(nums) == 1 { 34 | return nums[0] 35 | } else if len(nums) == 2 { 36 | return max(nums[0], nums[1]) 37 | } else if len(nums) == 3 { 38 | return max(nums[0], max(nums[1], nums[2])) 39 | } 40 | dp := make([]int, len(nums)) 41 | dp1 := make([]int, len(nums)) 42 | dp[0], dp[1] = nums[0], max(nums[0], nums[1]) 43 | dp1[0], dp1[1], dp1[2] = 0, nums[1], max(nums[1], nums[2]) 44 | for i := 2; i < len(nums); i++ { 45 | if i == len(nums)-1 { 46 | dp[i] = max(dp[i-1], nums[i]+dp1[i-2]) 47 | } else { 48 | dp[i] = max(dp[i-1], nums[i]+dp[i-2]) 49 | dp1[i] = max(dp1[i-1], nums[i]+dp1[i-2]) 50 | } 51 | } 52 | return dp[len(nums)-1] 53 | } 54 | ``` 55 | ## 337.打家劫舍III 56 | ```go 57 | func robIII(root *TreeNode) int { 58 | res := make([]int, 2) 59 | var dfs func(root *TreeNode) []int 60 | dfs = func(root *TreeNode) []int { 61 | if root == nil { 62 | return []int{0, 0} 63 | } 64 | left := make([]int, 2) 65 | right := make([]int, 2) 66 | center := make([]int, 2) 67 | 68 | left = dfs(root.Left) 69 | right = dfs(root.Right) 70 | center[0] = root.Val + left[1] + right[1] 71 | center[1] = max(left[0], left[1]) + max(right[0], right[1]) 72 | return center 73 | } 74 | res = dfs(root) 75 | return max(res[0], res[1]) 76 | } 77 | ``` 78 | -------------------------------------------------------------------------------- /day0605/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | import . "Code_Random_Thoughts/mypkg" 5 | 6 | func max(m, n int) int { 7 | if m > n { 8 | return m 9 | } 10 | return n 11 | } 12 | 13 | /* 14 | 2 1 1 2 15 | 2 1 2 16 | */ 17 | func rob(nums []int) int { 18 | if len(nums) == 1 { 19 | return nums[0] 20 | } else if len(nums) == 2 { 21 | return max(nums[0], nums[1]) 22 | } 23 | dp := make([]int, len(nums)) 24 | dp[0], dp[1] = nums[0], max(nums[0], nums[1]) 25 | for i := 2; i < len(nums); i++ { 26 | dp[i] = max(dp[i-1], nums[i]+dp[i-2]) 27 | fmt.Println(dp) 28 | } 29 | return dp[len(nums)-1] 30 | } 31 | 32 | func robII(nums []int) int { 33 | if len(nums) == 1 { 34 | return nums[0] 35 | } else if len(nums) == 2 { 36 | return max(nums[0], nums[1]) 37 | } else if len(nums) == 3 { 38 | return max(nums[0], max(nums[1], nums[2])) 39 | } 40 | dp := make([]int, len(nums)) 41 | dp1 := make([]int, len(nums)) 42 | dp[0], dp[1] = nums[0], max(nums[0], nums[1]) 43 | dp1[0], dp1[1], dp1[2] = 0, nums[1], max(nums[1], nums[2]) 44 | for i := 2; i < len(nums); i++ { 45 | if i == len(nums)-1 { 46 | dp[i] = max(dp[i-1], nums[i]+dp1[i-2]) 47 | } else { 48 | dp[i] = max(dp[i-1], nums[i]+dp[i-2]) 49 | dp1[i] = max(dp1[i-1], nums[i]+dp1[i-2]) 50 | } 51 | } 52 | return dp[len(nums)-1] 53 | } 54 | 55 | func robIII(root *TreeNode) int { 56 | res := make([]int, 2) 57 | var dfs func(root *TreeNode) []int 58 | dfs = func(root *TreeNode) []int { 59 | if root == nil { 60 | return []int{0, 0} 61 | } 62 | left := make([]int, 2) 63 | right := make([]int, 2) 64 | center := make([]int, 2) 65 | 66 | left = dfs(root.Left) 67 | right = dfs(root.Right) 68 | center[0] = root.Val + left[1] + right[1] 69 | center[1] = max(left[0], left[1]) + max(right[0], right[1]) 70 | return center 71 | } 72 | res = dfs(root) 73 | return max(res[0], res[1]) 74 | } 75 | -------------------------------------------------------------------------------- /day0606/Day49动态规划part10.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part10 2 | ## 121. 买卖股票的最佳时机 3 | ```go 4 | func maxProfit(prices []int) int { 5 | if len(prices) == 1 { 6 | return 0 7 | } 8 | dp := make([][]int, len(prices)) 9 | for i := 0; i < len(prices); i++ { 10 | tmp := make([]int, 2) 11 | dp[i] = tmp 12 | } 13 | dp[0][0] = 0 14 | dp[0][1] = -prices[0] 15 | for i := 1; i < len(prices); i++ { 16 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 17 | dp[i][1] = max(dp[i-1][1], -prices[i]) 18 | } 19 | return dp[len(prices)-1][0] 20 | } 21 | ``` 22 | ## 122.买卖股票的最佳时机II 23 | ```go 24 | func maxProfitII(prices []int) int { 25 | dp := make([][]int, len(prices)) 26 | for i := 0; i < len(prices); i++ { 27 | tmp := make([]int, 2) 28 | dp[i] = tmp 29 | } 30 | dp[0][1] = -prices[0] 31 | dp[0][0] = 0 32 | for i := 1; i < len(prices); i++ { 33 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 34 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 35 | } 36 | return dp[len(prices)-1][0] 37 | } 38 | ``` -------------------------------------------------------------------------------- /day0606/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func max(m, n int) int { 4 | if m > n { 5 | return m 6 | } 7 | return n 8 | } 9 | func maxProfit(prices []int) int { 10 | dp := [2][2]int{} 11 | dp[0][0] = -prices[0] 12 | dp[0][1] = 0 13 | for i := 1; i < len(prices); i++ { 14 | dp[i%2][0] = max(dp[(i-1)%2][0], -prices[i]) 15 | dp[i%2][1] = max(dp[(i-1)%2][1], dp[(i-1)%2][0]+prices[i]) 16 | } 17 | 18 | return dp[(len(prices)-1)%2][1] 19 | } 20 | 21 | func maxProfitII(prices []int) int { 22 | dp := make([][]int, len(prices)) 23 | for i := 0; i < len(prices); i++ { 24 | tmp := make([]int, 2) 25 | dp[i] = tmp 26 | } 27 | dp[0][1] = -prices[0] 28 | dp[0][0] = 0 29 | for i := 1; i < len(prices); i++ { 30 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 31 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 32 | } 33 | return dp[len(prices)-1][0] 34 | } 35 | -------------------------------------------------------------------------------- /day0607/Day50动态规划part11.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part11 2 | ## 123.买卖股票的最佳时机III 3 | ```go 4 | func maxProfit(prices []int) int { 5 | dp := make([][]int, len(prices)) 6 | for i := 0; i < len(prices); i++ { 7 | tmp := make([]int, 5) 8 | dp[i] = tmp 9 | } 10 | dp[0][0] = 0 11 | dp[0][1] = -prices[0] 12 | dp[0][2] = 0 13 | dp[0][3] = -prices[0] 14 | dp[0][4] = 0 15 | 16 | for i := 1; i < len(prices); i++ { 17 | dp[i][0] = dp[i-1][0] 18 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 19 | dp[i][2] = max(dp[i-1][2], dp[i-1][1]+prices[i]) 20 | dp[i][3] = max(dp[i-1][3], dp[i-1][2]-prices[i]) 21 | dp[i][4] = max(dp[i-1][4], dp[i-1][3]+prices[i]) 22 | } 23 | return max(dp[len(prices)-1][0], max(dp[len(prices)-1][2], dp[len(prices)-1][4])) 24 | } 25 | ``` 26 | ## 188.买卖股票的最佳时机IV 27 | ```go 28 | func maxProfitIV(k int, prices []int) int { 29 | dp := make([][]int, len(prices)) 30 | for i := 0; i < len(prices); i++ { 31 | tmp := make([]int, 2*k+1) 32 | dp[i] = tmp 33 | } 34 | for i := 0; i < 2*k+1; i++ { 35 | if i%2 == 0 { 36 | dp[0][i] = 0 37 | } else { 38 | dp[0][i] = -prices[0] 39 | } 40 | } 41 | 42 | for i := 1; i < len(prices); i++ { 43 | dp[i][0] = dp[i-1][0] 44 | for j := 1; j < 2*k+1; j++ { 45 | if j%2 != 0 { 46 | dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]-prices[i]) 47 | } else { 48 | dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]+prices[i]) 49 | } 50 | } 51 | } 52 | return dp[len(prices)-1][2*k] 53 | } 54 | ``` -------------------------------------------------------------------------------- /day0607/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func max(m, n int) int { 4 | if m > n { 5 | return m 6 | } 7 | return n 8 | } 9 | func maxProfit(prices []int) int { 10 | dp := make([][]int, len(prices)) 11 | for i := 0; i < len(prices); i++ { 12 | tmp := make([]int, 5) 13 | dp[i] = tmp 14 | } 15 | dp[0][0] = 0 16 | dp[0][1] = -prices[0] 17 | dp[0][2] = 0 18 | dp[0][3] = -prices[0] 19 | dp[0][4] = 0 20 | 21 | for i := 1; i < len(prices); i++ { 22 | dp[i][0] = dp[i-1][0] 23 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 24 | dp[i][2] = max(dp[i-1][2], dp[i-1][1]+prices[i]) 25 | dp[i][3] = max(dp[i-1][3], dp[i-1][2]-prices[i]) 26 | dp[i][4] = max(dp[i-1][4], dp[i-1][3]+prices[i]) 27 | } 28 | return max(dp[len(prices)-1][0], max(dp[len(prices)-1][2], dp[len(prices)-1][4])) 29 | } 30 | 31 | func maxProfitIV(k int, prices []int) int { 32 | dp := make([][]int, len(prices)) 33 | for i := 0; i < len(prices); i++ { 34 | tmp := make([]int, 2*k+1) 35 | dp[i] = tmp 36 | } 37 | for i := 0; i < 2*k+1; i++ { 38 | if i%2 == 0 { 39 | dp[0][i] = 0 40 | } else { 41 | dp[0][i] = -prices[0] 42 | } 43 | } 44 | 45 | for i := 1; i < len(prices); i++ { 46 | dp[i][0] = dp[i-1][0] 47 | for j := 1; j < 2*k+1; j++ { 48 | if j%2 != 0 { 49 | dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]-prices[i]) 50 | } else { 51 | dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]+prices[i]) 52 | } 53 | } 54 | } 55 | return dp[len(prices)-1][2*k] 56 | } 57 | -------------------------------------------------------------------------------- /day0608/Day51动态规划part12.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part12 2 | ## 309.最佳买卖股票时机含冷冻期 3 | ```go 4 | func maxProfit(prices []int) int { 5 | dp := make([][]int, len(prices)) 6 | for i := 0; i < len(prices); i++ { 7 | tmp := make([]int, 3) 8 | dp[i] = tmp 9 | } 10 | dp[0][0] = 0 11 | dp[0][1] = -prices[0] 12 | dp[0][2] = 0 13 | for i := 1; i < len(prices); i++ { 14 | dp[i][0] = max(dp[i-1][0], dp[i-1][2]) 15 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 16 | dp[i][2] = dp[i-1][1] + prices[i] 17 | } 18 | return max(dp[len(prices)-1][0], dp[len(prices)-1][2]) 19 | 20 | } 21 | ``` 22 | ## 714.买卖股票的最佳时机含手续费 23 | ```go 24 | func maxProfitII(prices []int, fee int) int { 25 | dp := make([][]int, len(prices)) 26 | for i := 0; i < len(prices); i++ { 27 | tmp := make([]int, 2) 28 | dp[i] = tmp 29 | } 30 | dp[0][1] = -prices[0] 31 | dp[0][0] = 0 32 | for i := 1; i < len(prices); i++ { 33 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]-fee) 34 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 35 | } 36 | return dp[len(prices)-1][0] 37 | } 38 | ``` -------------------------------------------------------------------------------- /day0608/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func max(m, n int) int { 4 | if m > n { 5 | return m 6 | } else { 7 | return n 8 | } 9 | } 10 | 11 | func maxProfit(prices []int) int { 12 | dp := make([][]int, len(prices)) 13 | for i := 0; i < len(prices); i++ { 14 | tmp := make([]int, 3) 15 | dp[i] = tmp 16 | } 17 | dp[0][0] = 0 18 | dp[0][1] = -prices[0] 19 | dp[0][2] = 0 20 | for i := 1; i < len(prices); i++ { 21 | dp[i][0] = max(dp[i-1][0], dp[i-1][2]) 22 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 23 | dp[i][2] = dp[i-1][1] + prices[i] 24 | } 25 | return max(dp[len(prices)-1][0], dp[len(prices)-1][2]) 26 | 27 | } 28 | 29 | func maxProfitII(prices []int, fee int) int { 30 | dp := make([][]int, len(prices)) 31 | for i := 0; i < len(prices); i++ { 32 | tmp := make([]int, 2) 33 | dp[i] = tmp 34 | } 35 | dp[0][1] = -prices[0] 36 | dp[0][0] = 0 37 | for i := 1; i < len(prices); i++ { 38 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]-fee) 39 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 40 | } 41 | return dp[len(prices)-1][0] 42 | } 43 | -------------------------------------------------------------------------------- /day0609/Day52动态规划part13.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part13 2 | ## 300.最长递增子序列 3 | ```go 4 | func lengthOfLIS(nums []int) int { 5 | if len(nums) == 1 { 6 | return 1 7 | } 8 | dp := make([]int, len(nums)) 9 | for i := 0; i < len(nums); i++ { 10 | dp[i] = 1 11 | } 12 | res := 0 13 | for i := 0; i < len(nums); i++ { 14 | for j := 0; j < i; j++ { 15 | if nums[i] > nums[j] { 16 | dp[i] = max(dp[i], dp[j]+1) 17 | } 18 | fmt.Println("i:", i, " j:", j) 19 | fmt.Println(dp) 20 | } 21 | if dp[i] > res { 22 | res = dp[i] 23 | } 24 | } 25 | return res 26 | } 27 | ``` 28 | ## 674. 最长连续递增序列 29 | ```go 30 | func findLengthOfLCIS(nums []int) int { 31 | if len(nums) == 0 { 32 | return 0 33 | } 34 | res, count := 1, 1 35 | for i := 0; i < len(nums)-1; i++ { 36 | if nums[i+1] > nums[i] { 37 | count++ 38 | } else { 39 | count = 1 40 | } 41 | if count > res { 42 | res = count 43 | } 44 | } 45 | return res 46 | } 47 | ``` 48 | ## 718. 最长重复子数组 49 | ```go 50 | func findLength(nums1 []int, nums2 []int) int { 51 | dp := make([][]int, len(nums1)) 52 | for i := 0; i < len(nums1); i++ { 53 | tmp := make([]int, len(nums2)) 54 | dp[i] = tmp 55 | } 56 | res := 0 57 | for i := 0; i < len(nums1); i++ { 58 | for j := 0; j < len(nums2); j++ { 59 | if nums1[i] == nums2[j] { 60 | if i-1 < 0 || j-1 < 0 { 61 | dp[i][j] = 1 62 | } else { 63 | dp[i][j] = dp[i-1][j-1] + 1 64 | } 65 | if dp[i][j] > res { 66 | res = dp[i][j] 67 | } 68 | } 69 | } 70 | } 71 | return res 72 | } 73 | ``` -------------------------------------------------------------------------------- /day0609/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func max(m, n int) int { 6 | if m > n { 7 | return m 8 | } 9 | return n 10 | } 11 | 12 | func lengthOfLIS(nums []int) int { 13 | if len(nums) == 1 { 14 | return 1 15 | } 16 | dp := make([]int, len(nums)) 17 | for i := 0; i < len(nums); i++ { 18 | dp[i] = 1 19 | } 20 | res := 0 21 | for i := 0; i < len(nums); i++ { 22 | for j := 0; j < i; j++ { 23 | if nums[i] > nums[j] { 24 | dp[i] = max(dp[i], dp[j]+1) 25 | } 26 | fmt.Println("i:", i, " j:", j) 27 | fmt.Println(dp) 28 | } 29 | if dp[i] > res { 30 | res = dp[i] 31 | } 32 | } 33 | return res 34 | } 35 | 36 | func findLengthOfLCIS(nums []int) int { 37 | if len(nums) == 0 { 38 | return 0 39 | } 40 | res, count := 1, 1 41 | for i := 0; i < len(nums)-1; i++ { 42 | if nums[i+1] > nums[i] { 43 | count++ 44 | } else { 45 | count = 1 46 | } 47 | if count > res { 48 | res = count 49 | } 50 | } 51 | return res 52 | } 53 | 54 | func findLength(nums1 []int, nums2 []int) int { 55 | dp := make([][]int, len(nums1)) 56 | for i := 0; i < len(nums1); i++ { 57 | tmp := make([]int, len(nums2)) 58 | dp[i] = tmp 59 | } 60 | res := 0 61 | for i := 0; i < len(nums1); i++ { 62 | for j := 0; j < len(nums2); j++ { 63 | if nums1[i] == nums2[j] { 64 | if i-1 < 0 || j-1 < 0 { 65 | dp[i][j] = 1 66 | } else { 67 | dp[i][j] = dp[i-1][j-1] + 1 68 | } 69 | if dp[i][j] > res { 70 | res = dp[i][j] 71 | } 72 | } 73 | } 74 | } 75 | return res 76 | } 77 | -------------------------------------------------------------------------------- /day0610/Day53动态规划part14.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part14 2 | ## 1143.最长公共子序列 3 | ```go 4 | func longestCommonSubsequence(text1 string, text2 string) int { 5 | dp := make([][]int, len(text1)+1) 6 | for i := 0; i < len(text1)+1; i++ { 7 | tmp := make([]int, len(text2)+1) 8 | dp[i] = tmp 9 | } 10 | res := 0 11 | for i := 1; i <= len(text1); i++ { 12 | for j := 1; j <= len(text2); j++ { 13 | if text1[i-1] == text2[j-1] { 14 | dp[i][j] = dp[i-1][j-1] + 1 15 | } else { 16 | dp[i][j] = max(dp[i-1][j], dp[i][j-1]) 17 | } 18 | if res < dp[i][j] { 19 | res = dp[i][j] 20 | } 21 | } 22 | } 23 | return res 24 | } 25 | ``` 26 | ## 1035.不相交的线 27 | ```go 28 | func maxUncrossedLines(nums1 []int, nums2 []int) int { 29 | dp := make([][]int, len(nums1)+1) 30 | for i := 0; i < len(nums1)+1; i++ { 31 | tmp := make([]int, len(nums2)+1) 32 | dp[i] = tmp 33 | } 34 | res := 0 35 | for i := 1; i <= len(nums1); i++ { 36 | for j := 1; j <= len(nums2); j++ { 37 | if nums1[i-1] == nums2[j-1] { 38 | dp[i][j] = dp[i-1][j-1] + 1 39 | } else { 40 | dp[i][j] = max(dp[i-1][j], dp[i][j-1]) 41 | } 42 | if res < dp[i][j] { 43 | res = dp[i][j] 44 | } 45 | } 46 | } 47 | return res 48 | } 49 | ``` 50 | ## 53. 最大子序和 51 | ```go 52 | func maxSubArray(nums []int) int { 53 | dp := make([]int, len(nums)) 54 | dp[0] = nums[0] 55 | res := 0 56 | for i := 0; i < len(nums); i++ { 57 | dp[i] = max(dp[i-1]+nums[i], nums[i]) 58 | if dp[i] > res { 59 | res = dp[i] 60 | } 61 | } 62 | return res 63 | } 64 | ``` -------------------------------------------------------------------------------- /day0610/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func max(m, n int) int { 4 | if m > n { 5 | return m 6 | } 7 | return n 8 | } 9 | 10 | func longestCommonSubsequence(text1 string, text2 string) int { 11 | dp := make([][]int, len(text1)+1) 12 | for i := 0; i < len(text1)+1; i++ { 13 | tmp := make([]int, len(text2)+1) 14 | dp[i] = tmp 15 | } 16 | res := 0 17 | for i := 1; i <= len(text1); i++ { 18 | for j := 1; j <= len(text2); j++ { 19 | if text1[i-1] == text2[j-1] { 20 | dp[i][j] = dp[i-1][j-1] + 1 21 | } else { 22 | dp[i][j] = max(dp[i-1][j], dp[i][j-1]) 23 | } 24 | if res < dp[i][j] { 25 | res = dp[i][j] 26 | } 27 | } 28 | } 29 | return res 30 | } 31 | 32 | func maxUncrossedLines(nums1 []int, nums2 []int) int { 33 | dp := make([][]int, len(nums1)+1) 34 | for i := 0; i < len(nums1)+1; i++ { 35 | tmp := make([]int, len(nums2)+1) 36 | dp[i] = tmp 37 | } 38 | res := 0 39 | for i := 1; i <= len(nums1); i++ { 40 | for j := 1; j <= len(nums2); j++ { 41 | if nums1[i-1] == nums2[j-1] { 42 | dp[i][j] = dp[i-1][j-1] + 1 43 | } else { 44 | dp[i][j] = max(dp[i-1][j], dp[i][j-1]) 45 | } 46 | if res < dp[i][j] { 47 | res = dp[i][j] 48 | } 49 | } 50 | } 51 | return res 52 | } 53 | 54 | func maxSubArray(nums []int) int { 55 | dp := make([]int, len(nums)) 56 | dp[0] = nums[0] 57 | res := 0 58 | for i := 0; i < len(nums); i++ { 59 | dp[i] = max(dp[i-1]+nums[i], nums[i]) 60 | if dp[i] > res { 61 | res = dp[i] 62 | } 63 | } 64 | return res 65 | } 66 | -------------------------------------------------------------------------------- /day0612/Day55动态规划part15.md: -------------------------------------------------------------------------------- 1 | # 392.判断子序列 2 | ## 392.判断子序列 3 | 1. 一维动态规划 4 | ```go 5 | func isSubsequence(s string, t string) bool { 6 | if len(s) == 0 { 7 | return true 8 | } 9 | if len(t) == 0 { 10 | return false 11 | } 12 | dp := make([]int, len(t)+1) 13 | for i := 0; i < len(dp); i++ { 14 | dp[i] = -1 15 | } 16 | for i := 1; i <= len(t); i++ { 17 | if s[dp[i-1]+1] == t[i-1] { 18 | dp[i] = dp[i-1] + 1 19 | } else { 20 | dp[i] = dp[i-1] 21 | } 22 | if dp[i]+1 == len(s) { 23 | return true 24 | } 25 | fmt.Println(dp) 26 | } 27 | if dp[len(t)]+1 == len(s) { 28 | return true 29 | } 30 | return false 31 | } 32 | ``` 33 | 2. 二维动态规划 34 | ```go 35 | func isSubsequence(s string, t string) bool { 36 | dp := make([][]int, len(s)+1) 37 | for i := 0; i < len(dp); i++ { 38 | tmp := make([]int, len(t)+1) 39 | dp[i] = tmp 40 | } 41 | for i := 1; i <= len(s); i++ { 42 | for j := 1; j <= len(t); j++ { 43 | if s[i-1] == t[j-1] { 44 | dp[i][j] = dp[i-1][j-1] + 1 45 | } else { 46 | dp[i][j] = dp[i][j-1] 47 | } 48 | } 49 | } 50 | if dp[len(s)][len(t)] == len(s) { 51 | return true 52 | } 53 | return false 54 | } 55 | ``` 56 | ## 115.不同的子序列 57 | ```go 58 | func numDistinct(s string, t string) int { 59 | dp := make([][]int, len(s)+1) 60 | for i := 0; i < len(dp); i++ { 61 | tmp := make([]int, len(t)+1) 62 | tmp[0] = 1 63 | dp[i] = tmp 64 | } 65 | for i := 1; i <= len(s); i++ { 66 | for j := 1; j <= len(t); j++ { 67 | if s[i-1] == t[j-1] { 68 | dp[i][j] = dp[i-1][j-1] + dp[i-1][j] 69 | } else { 70 | dp[i][j] = dp[i-1][j] 71 | } 72 | } 73 | } 74 | return dp[len(s)][len(t)] 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /day0612/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func isSubsequence(s string, t string) bool { 4 | dp := make([][]int, len(s)+1) 5 | for i := 0; i < len(dp); i++ { 6 | tmp := make([]int, len(t)+1) 7 | dp[i] = tmp 8 | } 9 | for i := 1; i <= len(s); i++ { 10 | for j := 1; j <= len(t); j++ { 11 | if s[i-1] == t[j-1] { 12 | dp[i][j] = dp[i-1][j-1] + 1 13 | } else { 14 | dp[i][j] = dp[i][j-1] 15 | } 16 | } 17 | } 18 | if dp[len(s)][len(t)] == len(s) { 19 | return true 20 | } 21 | return false 22 | } 23 | 24 | /* 25 | b a g 26 | [1 0 0 0] 27 | b [1 1 0 0] 28 | a [1 1 1 0] 29 | b [1 2 1 0] 30 | g [1 2 1 1] 31 | b [1 3 1 1] 32 | a [1 3 4 1] 33 | g [1 3 4 5] 34 | */ 35 | 36 | func numDistinct(s string, t string) int { 37 | dp := make([][]int, len(s)+1) 38 | for i := 0; i < len(dp); i++ { 39 | tmp := make([]int, len(t)+1) 40 | tmp[0] = 1 41 | dp[i] = tmp 42 | } 43 | for i := 1; i <= len(s); i++ { 44 | for j := 1; j <= len(t); j++ { 45 | if s[i-1] == t[j-1] { 46 | dp[i][j] = dp[i-1][j-1] + dp[i-1][j] 47 | } else { 48 | dp[i][j] = dp[i-1][j] 49 | } 50 | } 51 | } 52 | return dp[len(s)][len(t)] 53 | } 54 | -------------------------------------------------------------------------------- /day0613/Day56动态规划part16.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part16 2 | ## 583. 两个字符串的删除操作 3 | ```go 4 | func minDistance(word1 string, word2 string) int { 5 | dp := make([][]int, len(word1)+1) 6 | for i := 0; i < len(dp); i++ { 7 | tmp := make([]int, len(word2)+1) 8 | dp[i] = tmp 9 | } 10 | for i := 0; i < len(dp); i++ { 11 | dp[i][0] = i 12 | } 13 | for j := 0; j < len(dp[0]); j++ { 14 | dp[0][j] = j 15 | } 16 | for i := 1; i <= len(word1); i++ { 17 | for j := 1; j <= len(word2); j++ { 18 | if word1[i-1] == word2[j-1] { 19 | dp[i][j] = dp[i-1][j-1] 20 | } else { 21 | dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1) 22 | } 23 | } 24 | } 25 | return dp[len(word1)][len(word2)] 26 | } 27 | ``` 28 | ## 72. 编辑距离 29 | ```go 30 | func minDistanceII(word1 string, word2 string) int { 31 | dp := make([][]int, len(word1)+1) 32 | for i := 0; i < len(dp); i++ { 33 | tmp := make([]int, len(word2)+1) 34 | dp[i] = tmp 35 | } 36 | for i := 0; i < len(dp); i++ { 37 | dp[i][0] = i 38 | } 39 | for j := 0; j < len(dp[0]); j++ { 40 | dp[0][j] = j 41 | } 42 | for i := 1; i <= len(word1); i++ { 43 | for j := 1; j <= len(word2); j++ { 44 | if word1[i-1] == word2[j-1] { 45 | dp[i][j] = dp[i-1][j-1] 46 | } else { 47 | dp[i][j] = findMinimum(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+1) 48 | } 49 | } 50 | } 51 | return dp[len(word1)][len(word2)] 52 | } 53 | ``` -------------------------------------------------------------------------------- /day0613/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func max(m, n int) int { 4 | if m > n { 5 | return m 6 | } 7 | return n 8 | } 9 | 10 | func min(m, n int) int { 11 | if m < n { 12 | return m 13 | } 14 | return n 15 | } 16 | 17 | func minDistance(word1 string, word2 string) int { 18 | dp := make([][]int, len(word1)+1) 19 | for i := 0; i < len(dp); i++ { 20 | tmp := make([]int, len(word2)+1) 21 | dp[i] = tmp 22 | } 23 | for i := 0; i < len(dp); i++ { 24 | dp[i][0] = i 25 | } 26 | for j := 0; j < len(dp[0]); j++ { 27 | dp[0][j] = j 28 | } 29 | for i := 1; i <= len(word1); i++ { 30 | for j := 1; j <= len(word2); j++ { 31 | if word1[i-1] == word2[j-1] { 32 | dp[i][j] = dp[i-1][j-1] 33 | } else { 34 | dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1) 35 | } 36 | } 37 | } 38 | return dp[len(word1)][len(word2)] 39 | } 40 | 41 | func findMinimum(numbers ...int) int { 42 | if len(numbers) == 0 { 43 | panic("At least one number must be provided") 44 | } 45 | 46 | min := numbers[0] 47 | for _, num := range numbers { 48 | if num < min { 49 | min = num 50 | } 51 | } 52 | 53 | return min 54 | } 55 | 56 | func minDistanceII(word1 string, word2 string) int { 57 | dp := make([][]int, len(word1)+1) 58 | for i := 0; i < len(dp); i++ { 59 | tmp := make([]int, len(word2)+1) 60 | dp[i] = tmp 61 | } 62 | for i := 0; i < len(dp); i++ { 63 | dp[i][0] = i 64 | } 65 | for j := 0; j < len(dp[0]); j++ { 66 | dp[0][j] = j 67 | } 68 | for i := 1; i <= len(word1); i++ { 69 | for j := 1; j <= len(word2); j++ { 70 | if word1[i-1] == word2[j-1] { 71 | dp[i][j] = dp[i-1][j-1] 72 | } else { 73 | dp[i][j] = findMinimum(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+1) 74 | } 75 | } 76 | } 77 | return dp[len(word1)][len(word2)] 78 | } 79 | -------------------------------------------------------------------------------- /day0614/Day57动态规划part17.md: -------------------------------------------------------------------------------- 1 | # 第九章 动态规划part17 2 | ## 647. 回文子串 3 | 1. 动态规划 4 | ```go 5 | func countSubstrings(s string) int { 6 | dp := make([][]bool, len(s)) 7 | res := 0 8 | for i := 0; i < len(dp); i++ { 9 | tmp := make([]bool, len(s)) 10 | dp[i] = tmp 11 | } 12 | for i := len(s) - 1; i >= 0; i-- { 13 | for j := i; j < len(s); j++ { 14 | if s[i] == s[j] { 15 | if (j - i) <= 1 { 16 | dp[i][j] = true 17 | res++ 18 | } else if dp[i+1][j-1] { 19 | dp[i][j] = true 20 | res++ 21 | } 22 | } 23 | } 24 | } 25 | return res 26 | } 27 | ``` 28 | 2. 中心扩散 29 | ```go 30 | func countSubstrings(s string) int { 31 | result := 0 32 | for i := 0; i < len(s); i++ { 33 | result += extend(s, i, i, len(s)) // 以i为中心 34 | result += extend(s, i, i+1, len(s)) // 以i和i+1为中心 35 | } 36 | return result 37 | } 38 | 39 | func extend(s string, i int, j int, n int) int { 40 | res := 0 41 | for i >= 0 && j < n && s[i] == s[j] { 42 | i-- 43 | j++ 44 | res++ 45 | } 46 | return res 47 | } 48 | ``` 49 | ## 516.最长回文子序列 50 | ```go 51 | func longestPalindromeSubseq(s string) int { 52 | dp := make([][]int, len(s)+1) 53 | res := 0 54 | for i := 0; i < len(dp); i++ { 55 | tmp := make([]int, len(s)+1) 56 | //for j := 0; j < len(tmp); j++ { 57 | // tmp[j] = -1 58 | //} 59 | dp[i] = tmp 60 | } 61 | for i := len(s) - 1; i >= 0; i-- { 62 | for j := i; j < len(s); j++ { 63 | if s[i] == s[j] { 64 | if (j - i) <= 1 { 65 | dp[i][j] = j - i + 1 66 | } else { 67 | dp[i][j] = dp[i+1][j-1] + 2 68 | } 69 | if dp[i][j] > res { 70 | res = dp[i][j] 71 | } 72 | } else { 73 | dp[i][j] = max(dp[i+1][j], dp[i][j-1]) 74 | } 75 | } 76 | } 77 | return res 78 | } 79 | ``` -------------------------------------------------------------------------------- /day0614/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func isSubString(s string) bool { 4 | for i := 0; i < len(s)/2; i++ { 5 | if s[i] != s[len(s)-1-i] { 6 | return false 7 | } 8 | } 9 | return true 10 | } 11 | 12 | func countSubstrings(s string) int { 13 | dp := make([][]bool, len(s)) 14 | res := 0 15 | for i := 0; i < len(dp); i++ { 16 | tmp := make([]bool, len(s)) 17 | dp[i] = tmp 18 | } 19 | for i := len(s) - 1; i >= 0; i-- { 20 | for j := i; j < len(s); j++ { 21 | if s[i] == s[j] { 22 | if (j - i) <= 1 { 23 | dp[i][j] = true 24 | res++ 25 | } else if dp[i+1][j-1] { 26 | dp[i][j] = true 27 | res++ 28 | } 29 | } 30 | } 31 | } 32 | return res 33 | } 34 | 35 | func findMinimum(numbers ...int) int { 36 | if len(numbers) == 0 { 37 | panic("At least one number must be provided") 38 | } 39 | 40 | min := numbers[0] 41 | for _, num := range numbers { 42 | if num < min { 43 | min = num 44 | } 45 | } 46 | 47 | return min 48 | } 49 | 50 | func max(m, n int) int { 51 | if m > n { 52 | return m 53 | } 54 | return n 55 | } 56 | 57 | func longestPalindromeSubseq(s string) int { 58 | dp := make([][]int, len(s)+1) 59 | res := 0 60 | for i := 0; i < len(dp); i++ { 61 | tmp := make([]int, len(s)+1) 62 | //for j := 0; j < len(tmp); j++ { 63 | // tmp[j] = -1 64 | //} 65 | dp[i] = tmp 66 | } 67 | for i := len(s) - 1; i >= 0; i-- { 68 | for j := i; j < len(s); j++ { 69 | if s[i] == s[j] { 70 | if (j - i) <= 1 { 71 | dp[i][j] = j - i + 1 72 | } else { 73 | dp[i][j] = dp[i+1][j-1] + 2 74 | } 75 | if dp[i][j] > res { 76 | res = dp[i][j] 77 | } 78 | } else { 79 | dp[i][j] = max(dp[i+1][j], dp[i][j-1]) 80 | } 81 | } 82 | } 83 | return res 84 | } 85 | -------------------------------------------------------------------------------- /day0615/Day58单调栈part01.md: -------------------------------------------------------------------------------- 1 | # 第十章 单调栈part01 2 | ## 739. 每日温度 3 | ```go 4 | func dailyTemperatures(temperatures []int) []int { 5 | res := make([]int, len(temperatures)) 6 | numS := Stack{nums: []int{}} 7 | for i := 0; i < len(temperatures); i++ { 8 | if numS.IsEmpty() { 9 | numS.Push(i) 10 | } else { 11 | if temperatures[numS.Top()] >= temperatures[i] { 12 | numS.Push(i) 13 | } else { 14 | for !numS.IsEmpty() && temperatures[numS.Top()] < temperatures[i] { 15 | res[numS.Top()] = i - numS.Top() 16 | fmt.Println("res:", numS.Top(), " ", i-numS.Top()) 17 | numS.Pop() 18 | } 19 | numS.Push(i) 20 | } 21 | } 22 | fmt.Println("i:", temperatures[i], " ", numS.nums) 23 | } 24 | for !numS.IsEmpty() { 25 | res[numS.Top()] = 0 26 | numS.Pop() 27 | } 28 | return res 29 | } 30 | ``` 31 | ## 496.下一个更大元素 I 32 | ```go 33 | func nextGreaterElement(nums1 []int, nums2 []int) []int { 34 | numM := make(map[int]int) 35 | numS := Stack{nums: []int{}} 36 | for i := 0; i < len(nums2); i++ { 37 | if numS.IsEmpty() { 38 | numS.Push(i) 39 | } else { 40 | if nums2[numS.Top()] >= nums2[i] { 41 | numS.Push(i) 42 | } else { 43 | for !numS.IsEmpty() && nums2[numS.Top()] < nums2[i] { 44 | numM[nums2[numS.Top()]] = nums2[i] 45 | numS.Pop() 46 | } 47 | numS.Push(i) 48 | } 49 | } 50 | } 51 | for !numS.IsEmpty() { 52 | numM[nums2[numS.Top()]] = -1 53 | numS.Pop() 54 | } 55 | for i := 0; i < len(nums1); i++ { 56 | nums1[i] = numM[nums1[i]] 57 | } 58 | return nums1 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /day0615/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // Stack 是用于存放 int 的 栈 6 | type Stack struct { 7 | nums []int 8 | } 9 | 10 | // NewStack 返回 *kit.Stack 11 | func NewStack() *Stack { 12 | return &Stack{nums: []int{}} 13 | } 14 | 15 | // Push 把 n 放入 栈 16 | func (s *Stack) Push(n int) { 17 | s.nums = append(s.nums, n) 18 | } 19 | 20 | // Pop 从 s 中取出最后放入 栈 的值 21 | func (s *Stack) Pop() int { 22 | res := s.nums[len(s.nums)-1] 23 | s.nums = s.nums[:len(s.nums)-1] 24 | return res 25 | } 26 | 27 | // Len 返回 s 的长度 28 | func (s *Stack) Len() int { 29 | return len(s.nums) 30 | } 31 | 32 | // IsEmpty 反馈 s 是否为空 33 | func (s *Stack) IsEmpty() bool { 34 | return s.Len() == 0 35 | } 36 | 37 | func (s *Stack) Top() int { 38 | return s.nums[s.Len()-1] 39 | } 40 | 41 | func dailyTemperatures(temperatures []int) []int { 42 | res := make([]int, len(temperatures)) 43 | numS := Stack{nums: []int{}} 44 | for i := 0; i < len(temperatures); i++ { 45 | if numS.IsEmpty() { 46 | numS.Push(i) 47 | } else { 48 | if temperatures[numS.Top()] >= temperatures[i] { 49 | numS.Push(i) 50 | } else { 51 | for !numS.IsEmpty() && temperatures[numS.Top()] < temperatures[i] { 52 | res[numS.Top()] = i - numS.Top() 53 | fmt.Println("res:", numS.Top(), " ", i-numS.Top()) 54 | numS.Pop() 55 | } 56 | numS.Push(i) 57 | } 58 | } 59 | fmt.Println("i:", temperatures[i], " ", numS.nums) 60 | } 61 | for !numS.IsEmpty() { 62 | res[numS.Top()] = 0 63 | numS.Pop() 64 | } 65 | return res 66 | } 67 | 68 | func nextGreaterElement(nums1 []int, nums2 []int) []int { 69 | numM := make(map[int]int) 70 | numS := Stack{nums: []int{}} 71 | for i := 0; i < len(nums2); i++ { 72 | if numS.IsEmpty() { 73 | numS.Push(i) 74 | } else { 75 | if nums2[numS.Top()] >= nums2[i] { 76 | numS.Push(i) 77 | } else { 78 | for !numS.IsEmpty() && nums2[numS.Top()] < nums2[i] { 79 | numM[nums2[numS.Top()]] = nums2[i] 80 | numS.Pop() 81 | } 82 | numS.Push(i) 83 | } 84 | } 85 | } 86 | for !numS.IsEmpty() { 87 | numM[nums2[numS.Top()]] = -1 88 | numS.Pop() 89 | } 90 | for i := 0; i < len(nums1); i++ { 91 | nums1[i] = numM[nums1[i]] 92 | } 93 | return nums1 94 | } 95 | -------------------------------------------------------------------------------- /day0616/Day59单调栈part02.md: -------------------------------------------------------------------------------- 1 | # 第十章 单调栈part02 2 | ## 503.下一个更大元素II 3 | ```go 4 | func nextGreaterElements(temperatures []int) []int { 5 | lenT := len(temperatures) 6 | res := make([]int, lenT) 7 | for i := 0; i < len(res); i++ { 8 | res[i] = -1 9 | } 10 | numS := Stack{nums: []int{}} 11 | numS.Push(0) 12 | temperatures = append(temperatures, temperatures...) 13 | for i := 0; i < len(temperatures); i++ { 14 | if temperatures[numS.Top()] < temperatures[i] { 15 | for !numS.IsEmpty() && temperatures[numS.Top()] < temperatures[i] { 16 | res[numS.Top()] = temperatures[i] 17 | fmt.Println("res:", numS.Top(), " ", i%lenT-numS.Top()) 18 | numS.Pop() 19 | } 20 | } 21 | if i < lenT { 22 | numS.Push(i % lenT) 23 | } else if numS.IsEmpty() { 24 | break 25 | } 26 | fmt.Println("i:", temperatures[i], " ", numS.nums) 27 | } 28 | for !numS.IsEmpty() { 29 | res[numS.Top()] = -1 30 | numS.Pop() 31 | } 32 | return res 33 | } 34 | ``` 35 | ## 42. 接雨水 36 | ```go 37 | func trap(height []int) int { 38 | lenT := len(height) 39 | right := 0 40 | mid := 0 41 | res := 0 42 | numS := Stack{nums: []int{}} 43 | numS.Push(0) 44 | for i := 0; i < lenT; i++ { 45 | if height[numS.Top()] < height[i] { 46 | right = height[i] 47 | for !numS.IsEmpty() && height[numS.Top()] < height[i] { 48 | mid = height[numS.Pop()] 49 | if !numS.IsEmpty() { 50 | res += (min(right, height[numS.Top()]) - mid) * (i - numS.Top() - 1) 51 | } 52 | } 53 | } else if height[numS.Top()] == height[i] { 54 | numS.Pop() 55 | //numS.Push(i) 56 | } 57 | numS.Push(i) 58 | } 59 | return res 60 | } 61 | ``` 62 | -------------------------------------------------------------------------------- /day0616/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // Stack 是用于存放 int 的 栈 6 | type Stack struct { 7 | nums []int 8 | } 9 | 10 | // NewStack 返回 *kit.Stack 11 | func NewStack() *Stack { 12 | return &Stack{nums: []int{}} 13 | } 14 | 15 | // Push 把 n 放入 栈 16 | func (s *Stack) Push(n int) { 17 | s.nums = append(s.nums, n) 18 | } 19 | 20 | // Pop 从 s 中取出最后放入 栈 的值 21 | func (s *Stack) Pop() int { 22 | res := s.nums[len(s.nums)-1] 23 | s.nums = s.nums[:len(s.nums)-1] 24 | return res 25 | } 26 | 27 | // Len 返回 s 的长度 28 | func (s *Stack) Len() int { 29 | return len(s.nums) 30 | } 31 | 32 | // IsEmpty 反馈 s 是否为空 33 | func (s *Stack) IsEmpty() bool { 34 | return s.Len() == 0 35 | } 36 | 37 | func (s *Stack) Top() int { 38 | return s.nums[s.Len()-1] 39 | } 40 | 41 | func nextGreaterElements(temperatures []int) []int { 42 | lenT := len(temperatures) 43 | res := make([]int, lenT) 44 | for i := 0; i < len(res); i++ { 45 | res[i] = -1 46 | } 47 | numS := Stack{nums: []int{}} 48 | numS.Push(0) 49 | temperatures = append(temperatures, temperatures...) 50 | for i := 0; i < len(temperatures); i++ { 51 | if temperatures[numS.Top()] < temperatures[i] { 52 | for !numS.IsEmpty() && temperatures[numS.Top()] < temperatures[i] { 53 | res[numS.Top()] = temperatures[i] 54 | fmt.Println("res:", numS.Top(), " ", i%lenT-numS.Top()) 55 | numS.Pop() 56 | } 57 | } 58 | if i < lenT { 59 | numS.Push(i % lenT) 60 | } else if numS.IsEmpty() { 61 | break 62 | } 63 | fmt.Println("i:", temperatures[i], " ", numS.nums) 64 | } 65 | for !numS.IsEmpty() { 66 | res[numS.Top()] = -1 67 | numS.Pop() 68 | } 69 | return res 70 | } 71 | 72 | func min(m, n int) int { 73 | if m < n { 74 | return m 75 | } 76 | return n 77 | } 78 | 79 | func trap(height []int) int { 80 | lenT := len(height) 81 | right := 0 82 | mid := 0 83 | res := 0 84 | numS := Stack{nums: []int{}} 85 | numS.Push(0) 86 | for i := 0; i < lenT; i++ { 87 | if height[numS.Top()] < height[i] { 88 | right = height[i] 89 | for !numS.IsEmpty() && height[numS.Top()] < height[i] { 90 | mid = height[numS.Pop()] 91 | if !numS.IsEmpty() { 92 | res += (min(right, height[numS.Top()]) - mid) * (i - numS.Top() - 1) 93 | } 94 | } 95 | } else if height[numS.Top()] == height[i] { 96 | numS.Pop() 97 | //numS.Push(i) 98 | } 99 | numS.Push(i) 100 | } 101 | return res 102 | } 103 | -------------------------------------------------------------------------------- /day0617/Day60单调栈part03.md: -------------------------------------------------------------------------------- 1 | # 第十章 单调栈part03 2 | ## 84.柱状图中最大的矩形 3 | ```go 4 | func largestRectangleArea(heights []int) int { 5 | heights = append([]int{0}, append(heights, 0)...) 6 | lenH := len(heights) 7 | numS := Stack{nums: []int{}} 8 | mid := 0 9 | res := 0 10 | numS.Push(0) 11 | for i := 0; i < lenH; i++ { 12 | if heights[i] < heights[numS.Top()] { 13 | for !numS.IsEmpty() && heights[i] < heights[numS.Top()] { 14 | mid = heights[numS.Top()] 15 | numS.Pop() 16 | res = max(res, mid*(i-numS.Top()-1)) 17 | } 18 | } 19 | numS.Push(i) 20 | } 21 | return res 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /day0617/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // Stack 是用于存放 int 的 栈 4 | type Stack struct { 5 | nums []int 6 | } 7 | 8 | // NewStack 返回 *kit.Stack 9 | func NewStack() *Stack { 10 | return &Stack{nums: []int{}} 11 | } 12 | 13 | // Push 把 n 放入 栈 14 | func (s *Stack) Push(n int) { 15 | s.nums = append(s.nums, n) 16 | } 17 | 18 | // Pop 从 s 中取出最后放入 栈 的值 19 | func (s *Stack) Pop() int { 20 | res := s.nums[len(s.nums)-1] 21 | s.nums = s.nums[:len(s.nums)-1] 22 | return res 23 | } 24 | 25 | // Len 返回 s 的长度 26 | func (s *Stack) Len() int { 27 | return len(s.nums) 28 | } 29 | 30 | // IsEmpty 反馈 s 是否为空 31 | func (s *Stack) IsEmpty() bool { 32 | return s.Len() == 0 33 | } 34 | 35 | func (s *Stack) Top() int { 36 | return s.nums[s.Len()-1] 37 | } 38 | 39 | func min(m, n int) int { 40 | if m < n { 41 | return m 42 | } 43 | return n 44 | } 45 | 46 | func max(m, n int) int { 47 | if m > n { 48 | return m 49 | } 50 | return n 51 | } 52 | 53 | func largestRectangleArea(heights []int) int { 54 | heights = append([]int{0}, append(heights, 0)...) 55 | lenH := len(heights) 56 | numS := Stack{nums: []int{}} 57 | mid := 0 58 | res := 0 59 | numS.Push(0) 60 | for i := 0; i < lenH; i++ { 61 | if heights[i] < heights[numS.Top()] { 62 | for !numS.IsEmpty() && heights[i] < heights[numS.Top()] { 63 | mid = heights[numS.Top()] 64 | numS.Pop() 65 | res = max(res, mid*(i-numS.Top()-1)) 66 | } 67 | } 68 | numS.Push(i) 69 | } 70 | return res 71 | } 72 | -------------------------------------------------------------------------------- /day0618/Day61 总结篇.md: -------------------------------------------------------------------------------- 1 | # 代码随想录算法训练营13期 2 | 3 | 一刷完毕! 4 | 上次猛刷算法还是去年找实习的时候,虽然比起LeetCode动辄五六百七八百道的大佬还差得远,但是至少有一些基础题的结题思路了。 5 | 另外感觉还有许多东西需要补充,罗列一下: 6 | 1. 各种排序算法 7 | 2. 图论、并查集 8 | 3. 分治算法 9 | 4. 模拟题 10 | 5. KMP巩固 11 | 6. 贪心巩固 12 | 7. 二刷…… 13 | 14 | 另外吐槽一下Go的岗位和Go开发者真的好少啊… 15 | 茫茫人海中能看到一个同样耕耘Golang的老哥给了我莫大前进的动力,祝Golang生态越来越好,工资约拿越高🎉 -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module Code_Random_Thoughts 2 | 3 | go 1.19 4 | 5 | require github.com/halfrost/LeetCode-Go/structures v0.0.0-20230408040206-3200de1f73f5 // indirect 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/halfrost/LeetCode-Go/structures v0.0.0-20230408040206-3200de1f73f5 h1:f1Z/na9xa9jkDocCH+OK1R44JM2+NUk5vXLvAKmkeLM= 2 | github.com/halfrost/LeetCode-Go/structures v0.0.0-20230408040206-3200de1f73f5/go.mod h1:PiB3scEe5vQhgf3BFfrj/wwApeH+2yyPRF3Jqpq+7AY= 3 | -------------------------------------------------------------------------------- /mypkg/structDef.go: -------------------------------------------------------------------------------- 1 | package mypkg 2 | 3 | type ListNode struct { 4 | Val int 5 | Next *ListNode 6 | } 7 | 8 | type TreeNode struct { 9 | Val int 10 | Left *TreeNode 11 | Right *TreeNode 12 | } 13 | --------------------------------------------------------------------------------