Skip to content

Commit 9ae0981

Browse files
committed
basic: update
Change-Id: I4aa9981ace72fa45481afa4a08735cdf5dfccfdd
1 parent 640eec4 commit 9ae0981

File tree

6 files changed

+214
-9
lines changed

6 files changed

+214
-9
lines changed

go/basic/dp/dp.go

+37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package dp
22

3+
import (
4+
"sort"
5+
6+
"github.com/qieguo2016/algorithm/go/basic/util"
7+
)
8+
39
/**
410
* 求最大和子串,求给定整数数组中和最大的连续子串,输出最大和
511
* arr: 输入整数数组,至少有一个元素
@@ -17,3 +23,34 @@ func GetMaxSum(arr []int) int {
1723
}
1824
return maxSum
1925
}
26+
27+
// 给定金额用最少硬币数兑换
28+
// 求极值一般会考虑使用动态规划。用dp[i]表示i元的最少硬币兑换数,则状态转移方程:
29+
// dp[i]=min(dp[i-c])+1, for c in coins(遍历硬币组合)
30+
// dp[11] = min(dp[6], d[9], dp[10])+1
31+
// dp[1] = min(dp[-4], dp[-1], dp[0]) + 1
32+
// dp[0] = 0
33+
// dp[<0] invalid,用amount+1代替(硬币最小面值为1,最小有amount个,+1标识非法)
34+
// dp有两种模式,一种在迭代的时候增加记忆数组,另外一种是上来先算记忆数组
35+
// PS: 这个兑换有个特例,就是各种硬币是倍数关系的时候,这个时候退化成贪婪模式
36+
37+
func coinChange(coins []int, amount int) int {
38+
dp := make([]int, amount+1) // dp[0]为边界,需要amount+1个
39+
for i := 0; i < amount+1; i++ {
40+
dp[i] = amount + 1 // 默认都非法
41+
}
42+
sort.Ints(coins)
43+
dp[0] = 0
44+
for i := 1; i <= amount; i++ {
45+
for j := 0; j < len(coins); j++ {
46+
if coins[j] > i {
47+
break
48+
}
49+
dp[i] = util.Min(dp[i], dp[i-coins[j]]+1)
50+
}
51+
}
52+
if dp[amount] > amount {
53+
return -1
54+
}
55+
return dp[amount]
56+
}

go/basic/heap/heap.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package heap
22

33
import (
44
"sort"
5+
6+
"github.com/qieguo2016/algorithm/go/basic/util"
57
)
68

79
// SmallRootDown 小根堆向下调整
@@ -23,7 +25,7 @@ func SmallRootDown(target []int, from int, to int) {
2325
}
2426

2527
// 父节点取小节点
26-
swap(target, smaller, parent)
28+
util.Swap(target, smaller, parent)
2729
SmallRootDown(target, parent, to)
2830
}
2931

go/basic/heap/heap_example_test.go

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package heap_test
2+
3+
import (
4+
"container/heap"
5+
"fmt"
6+
"testing"
7+
)
8+
9+
type myHeap []int
10+
11+
func (h *myHeap) Less(i, j int) bool {
12+
return (*h)[i] < (*h)[j]
13+
}
14+
15+
func (h *myHeap) Swap(i, j int) {
16+
(*h)[i], (*h)[j] = (*h)[j], (*h)[i]
17+
}
18+
19+
func (h *myHeap) Len() int {
20+
return len(*h)
21+
}
22+
23+
func (h *myHeap) Pop() (v interface{}) {
24+
*h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1]
25+
return
26+
}
27+
28+
func (h *myHeap) Push(v interface{}) {
29+
*h = append(*h, v.(int))
30+
}
31+
32+
func TestHeap(t *testing.T) {
33+
h := new(myHeap)
34+
35+
for i := 20; i > 10; i-- {
36+
h.Push(i)
37+
}
38+
heap.Init(h)
39+
40+
for i := 10; i > 0; i-- {
41+
heap.Push(h, i)
42+
}
43+
44+
for i := 1; h.Len() > 0; i++ {
45+
x := heap.Pop(h).(int)
46+
if i < 20 {
47+
heap.Push(h, 20+i)
48+
}
49+
fmt.Println(x)
50+
}
51+
}
52+
53+
// An Item is something we manage in a priority queue.
54+
type Item struct {
55+
value string // The value of the item; arbitrary.
56+
priority int // The priority of the item in the queue.
57+
// The index is needed by update and is maintained by the heap.Interface methods.
58+
index int // The index of the item in the heap.
59+
}
60+
61+
// A PriorityQueue implements heap.Interface and holds Items.
62+
type PriorityQueue []*Item
63+
64+
func (pq PriorityQueue) Len() int { return len(pq) }
65+
66+
func (pq PriorityQueue) Less(i, j int) bool {
67+
// We want Pop to give us the highest, not lowest, priority so we use greater than here.
68+
return pq[i].priority > pq[j].priority
69+
}
70+
71+
func (pq PriorityQueue) Swap(i, j int) {
72+
pq[i], pq[j] = pq[j], pq[i]
73+
pq[i].index = i
74+
pq[j].index = j
75+
}
76+
77+
func (pq *PriorityQueue) Push(x interface{}) {
78+
n := len(*pq)
79+
item := x.(*Item)
80+
item.index = n
81+
*pq = append(*pq, item)
82+
}
83+
84+
func (pq *PriorityQueue) Pop() interface{} {
85+
old := *pq
86+
n := len(old)
87+
item := old[n-1]
88+
old[n-1] = nil // avoid memory leak
89+
item.index = -1 // for safety
90+
*pq = old[0 : n-1]
91+
return item
92+
}
93+
94+
// update modifies the priority and value of an Item in the queue.
95+
func (pq *PriorityQueue) update(item *Item, value string, priority int) {
96+
item.value = value
97+
item.priority = priority
98+
heap.Fix(pq, item.index)
99+
}
100+
101+
// This example creates a PriorityQueue with some items, adds and manipulates an item,
102+
// and then removes the items in priority order.
103+
func Example_priorityQueue() {
104+
// Some items and their priorities.
105+
items := map[string]int{
106+
"banana": 3, "apple": 2, "pear": 4,
107+
}
108+
109+
// Create a priority queue, put the items in it, and
110+
// establish the priority queue (heap) invariants.
111+
pq := make(PriorityQueue, len(items))
112+
i := 0
113+
for value, priority := range items {
114+
pq[i] = &Item{
115+
value: value,
116+
priority: priority,
117+
index: i,
118+
}
119+
i++
120+
}
121+
heap.Init(&pq)
122+
123+
// Insert a new item and then modify its priority.
124+
item := &Item{
125+
value: "orange",
126+
priority: 1,
127+
}
128+
heap.Push(&pq, item)
129+
pq.update(item, item.value, 5)
130+
131+
// Take the items out; they arrive in decreasing priority order.
132+
for pq.Len() > 0 {
133+
item := heap.Pop(&pq).(*Item)
134+
fmt.Printf("%.2d:%s ", item.priority, item.value)
135+
}
136+
// Output:
137+
// 05:orange 04:pear 03:banana 02:apple
138+
}

go/basic/heap/heap_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package heap
33
import (
44
"fmt"
55
"testing"
6+
7+
"github.com/qieguo2016/algorithm/go/basic/util"
68
)
79

810
func printHeap(arr []int) {
@@ -26,7 +28,7 @@ func printHeap(arr []int) {
2628

2729
func TestSmallRootHeap(t *testing.T) {
2830
for i := 0; i < 2; i++ {
29-
arr := makeRandomArray(7)
31+
arr := util.MakeRandomArray(7)
3032
fmt.Printf("origin arr=%v\n", arr)
3133
NewSmallRootHeap(arr)
3234
fmt.Printf("heap arr=%v\n", arr)

go/basic/util.go

-7
This file was deleted.

go/basic/util/util.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package util
2+
3+
import (
4+
"math/rand"
5+
)
6+
7+
func Swap(arr []int, i int, j int) {
8+
tmp := arr[i]
9+
arr[i] = arr[j]
10+
arr[j] = tmp
11+
}
12+
13+
func Min(i, j int) int {
14+
if i < j {
15+
return i
16+
}
17+
return j
18+
}
19+
20+
func Max(i, j int) int {
21+
if i > j {
22+
return i
23+
}
24+
return j
25+
}
26+
27+
func MakeRandomArray(n int) []int {
28+
ret := make([]int, n)
29+
for i := 0; i < n; i++ {
30+
ret[i] = rand.Intn(n * 10)
31+
}
32+
return ret
33+
}

0 commit comments

Comments
 (0)