├── .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 |
--------------------------------------------------------------------------------