mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 22:28:40 +08:00 
			
		
		
		
	feat(go/greedy): add greedy in go code (#648)
This commit is contained in:
		
							
								
								
									
										27
									
								
								codes/go/chapter_greedy/coin_change_greedy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								codes/go/chapter_greedy/coin_change_greedy.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					// File: coin_change_greedy.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 零钱兑换:贪心 */
 | 
				
			||||||
 | 
					func coinChangeGreedy(coins []int, amt int) int {
 | 
				
			||||||
 | 
						// 假设 coins 列表有序
 | 
				
			||||||
 | 
						i := len(coins) - 1
 | 
				
			||||||
 | 
						count := 0
 | 
				
			||||||
 | 
						// 循环进行贪心选择,直到无剩余金额
 | 
				
			||||||
 | 
						for amt > 0 {
 | 
				
			||||||
 | 
							// 找到小于且最接近剩余金额的硬币
 | 
				
			||||||
 | 
							for coins[i] > amt {
 | 
				
			||||||
 | 
								i--
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// 选择 coins[i]
 | 
				
			||||||
 | 
							amt -= coins[i]
 | 
				
			||||||
 | 
							count++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 若未找到可行方案,则返回 -1
 | 
				
			||||||
 | 
						if amt != 0 {
 | 
				
			||||||
 | 
							return -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return count
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								codes/go/chapter_greedy/coin_change_greedy_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								codes/go/chapter_greedy/coin_change_greedy_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					// File: coin_change_greedy_test.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestCoinChangeGreedy(t *testing.T) {
 | 
				
			||||||
 | 
						// 贪心:能够保证找到全局最优解
 | 
				
			||||||
 | 
						coins := []int{1, 5, 10, 20, 50, 100}
 | 
				
			||||||
 | 
						amt := 186
 | 
				
			||||||
 | 
						res := coinChangeGreedy(coins, amt)
 | 
				
			||||||
 | 
						fmt.Printf("coins = %v, amt = %d\n", coins, amt)
 | 
				
			||||||
 | 
						fmt.Printf("凑到 %d 所需的最少硬币数量为 %d\n", amt, res)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 贪心:无法保证找到全局最优解
 | 
				
			||||||
 | 
						coins = []int{1, 20, 50}
 | 
				
			||||||
 | 
						amt = 60
 | 
				
			||||||
 | 
						res = coinChangeGreedy(coins, amt)
 | 
				
			||||||
 | 
						fmt.Printf("coins = %v, amt = %d\n", coins, amt)
 | 
				
			||||||
 | 
						fmt.Printf("凑到 %d 所需的最少硬币数量为 %d\n", amt, res)
 | 
				
			||||||
 | 
						fmt.Println("实际上需要的最少数量为 3 ,即 20 + 20 + 20")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 贪心:无法保证找到全局最优解
 | 
				
			||||||
 | 
						coins = []int{1, 49, 50}
 | 
				
			||||||
 | 
						amt = 98
 | 
				
			||||||
 | 
						res = coinChangeGreedy(coins, amt)
 | 
				
			||||||
 | 
						fmt.Printf("coins = %v, amt = %d\n", coins, amt)
 | 
				
			||||||
 | 
						fmt.Printf("凑到 %d 所需的最少硬币数量为 %d\n", amt, res)
 | 
				
			||||||
 | 
						fmt.Println("实际上需要的最少数量为 2 ,即 49 + 49")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								codes/go/chapter_greedy/fractional_knapsack.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								codes/go/chapter_greedy/fractional_knapsack.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					// File: fractional_knapsack.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "sort"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 物品 */
 | 
				
			||||||
 | 
					type Item struct {
 | 
				
			||||||
 | 
						w int // 物品重量
 | 
				
			||||||
 | 
						v int // 物品价值
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 分数背包:贪心 */
 | 
				
			||||||
 | 
					func fractionalKnapsack(wgt []int, val []int, cap int) float64 {
 | 
				
			||||||
 | 
						// 创建物品列表,包含两个属性:重量、价值
 | 
				
			||||||
 | 
						items := make([]Item, len(wgt))
 | 
				
			||||||
 | 
						for i := 0; i < len(wgt); i++ {
 | 
				
			||||||
 | 
							items[i] = Item{wgt[i], val[i]}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 按照单位价值 item.v / item.w 从高到低进行排序
 | 
				
			||||||
 | 
						sort.Slice(items, func(i, j int) bool {
 | 
				
			||||||
 | 
							return float64(items[i].v)/float64(items[i].w) > float64(items[j].v)/float64(items[j].w)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						// 循环贪心选择
 | 
				
			||||||
 | 
						res := 0.0
 | 
				
			||||||
 | 
						for _, item := range items {
 | 
				
			||||||
 | 
							if item.w <= cap {
 | 
				
			||||||
 | 
								// 若剩余容量充足,则将当前物品整个装进背包
 | 
				
			||||||
 | 
								res += float64(item.v)
 | 
				
			||||||
 | 
								cap -= item.w
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// 若剩余容量不足,则将当前物品的一部分装进背包
 | 
				
			||||||
 | 
								res += float64(item.v) / float64(item.w) * float64(cap)
 | 
				
			||||||
 | 
								// 已无剩余容量,因此跳出循环
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								codes/go/chapter_greedy/fractional_knapsack_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								codes/go/chapter_greedy/fractional_knapsack_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					// File: fractional_knapsack_test.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFractionalKnapsack(t *testing.T) {
 | 
				
			||||||
 | 
						wgt := []int{10, 20, 30, 40, 50}
 | 
				
			||||||
 | 
						val := []int{50, 120, 150, 210, 240}
 | 
				
			||||||
 | 
						capacity := 50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 贪心算法
 | 
				
			||||||
 | 
						res := fractionalKnapsack(wgt, val, capacity)
 | 
				
			||||||
 | 
						fmt.Println("不超过背包容量的最大物品价值为", res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								codes/go/chapter_greedy/max_capacity.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								codes/go/chapter_greedy/max_capacity.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					// File: max_capacity.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "math"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 最大容量:贪心 */
 | 
				
			||||||
 | 
					func maxCapacity(ht []int) int {
 | 
				
			||||||
 | 
						// 初始化 i, j 分列数组两端
 | 
				
			||||||
 | 
						i, j := 0, len(ht)-1
 | 
				
			||||||
 | 
						// 初始最大容量为 0
 | 
				
			||||||
 | 
						res := 0
 | 
				
			||||||
 | 
						// 循环贪心选择,直至两板相遇
 | 
				
			||||||
 | 
						for i < j {
 | 
				
			||||||
 | 
							// 更新最大容量
 | 
				
			||||||
 | 
							capacity := int(math.Min(float64(ht[i]), float64(ht[j]))) * (j - i)
 | 
				
			||||||
 | 
							res = int(math.Max(float64(res), float64(capacity)))
 | 
				
			||||||
 | 
							// 向内移动短板
 | 
				
			||||||
 | 
							if ht[i] < ht[j] {
 | 
				
			||||||
 | 
								i++
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								j--
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								codes/go/chapter_greedy/max_capacity_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								codes/go/chapter_greedy/max_capacity_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					// File: max_capacity_test.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestMaxCapacity(t *testing.T) {
 | 
				
			||||||
 | 
						ht := []int{3, 8, 5, 2, 7, 7, 3, 4}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 贪心算法
 | 
				
			||||||
 | 
						res := maxCapacity(ht)
 | 
				
			||||||
 | 
						fmt.Println("最大容量为", res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								codes/go/chapter_greedy/max_product_cutting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								codes/go/chapter_greedy/max_product_cutting.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					// File: max_product_cutting.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "math"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 最大切分乘积:贪心 */
 | 
				
			||||||
 | 
					func maxProductCutting(n int) int {
 | 
				
			||||||
 | 
						// 当 n <= 3 时,必须切分出一个 1
 | 
				
			||||||
 | 
						if n <= 3 {
 | 
				
			||||||
 | 
							return 1 * (n - 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 贪心地切分出 3 ,a 为 3 的个数,b 为余数
 | 
				
			||||||
 | 
						a := n / 3
 | 
				
			||||||
 | 
						b := n % 3
 | 
				
			||||||
 | 
						if b == 1 {
 | 
				
			||||||
 | 
							// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
 | 
				
			||||||
 | 
							return int(math.Pow(3, float64(a-1))) * 2 * 2
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if b == 2 {
 | 
				
			||||||
 | 
							// 当余数为 2 时,不做处理
 | 
				
			||||||
 | 
							return int(math.Pow(3, float64(a))) * 2
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 当余数为 0 时,不做处理
 | 
				
			||||||
 | 
						return int(math.Pow(3, float64(a)))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								codes/go/chapter_greedy/max_product_cutting_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								codes/go/chapter_greedy/max_product_cutting_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					// File: max_product_cutting_test.go
 | 
				
			||||||
 | 
					// Created Time: 2023-07-23
 | 
				
			||||||
 | 
					// Author: Reanon (793584285@qq.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package chapter_greedy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestMaxProductCutting(t *testing.T) {
 | 
				
			||||||
 | 
						n := 58
 | 
				
			||||||
 | 
						// 贪心算法
 | 
				
			||||||
 | 
						res := maxProductCutting(n)
 | 
				
			||||||
 | 
						fmt.Println("最大切分乘积为", res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user