Skip to content

Commit 9ce64ea

Browse files
committed
添加算法实例,leetCode第一题
1 parent 46139ff commit 9ce64ea

15 files changed

+635
-16
lines changed

Cache/lfu.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package Cache
22

33
import (
44
"fmt"
5-
"github.com/chanxuehong/util/math"
65
"github.com/yezihack/math/DoubleLinedList"
6+
"math"
77
)
88

99
/* LFU(least frequently used) 最不常用使用淘汰算法 */
@@ -49,7 +49,7 @@ func (f *LFUCache) updateFreq(node *DoubleLinedList.DoubleNode) {
4949
node.Freq = freq
5050
//新的频率了, 需要判断是否在缓存中
5151
if _, ok := f.cacheFreq[freq]; !ok { //不存在缓存中, 则创建新的.
52-
f.cacheFreq[freq] = DoubleLinedList.New(math.MaxUint)
52+
f.cacheFreq[freq] = DoubleLinedList.New(math.MaxInt32)
5353
}
5454
f.cacheFreq[freq].Append(node)
5555
}

Cache/lru.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"github.com/yezihack/math/DoubleLinedList"
55
)
66

7-
/* LRU(least recently used) 最少最近使用淘汰算法 */
7+
/* LRU(least recently used) 最近最少使用淘汰算法 */
88
/*
99
实现思路:
1010
1.使用到的数据, 放头部

DynamicProgramming/dp_test.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package DynamicProgramming
2+
3+
import (
4+
"testing"
5+
)
6+
7+
//算法
8+
// 先正常思维
9+
// 逆向思维
10+
// 递推思维 逐一推导结果,在此发现规律.
11+
12+
//动态规划算法Dynamic Programming(递推) 动态递推
13+
//对问题求解时,将问题分解成若干个子问题,
14+
/*
15+
求解方法:
16+
1.递归 + 记忆化 -> 递推
17+
2.状态的定义
18+
3.状态的转移方程
19+
4.最优子结构
20+
*/
21+
22+
//第一个题 ,非波纳契
23+
//第一种解法:递归
24+
func fab(n int) int {
25+
if n <= 2 {
26+
return 1
27+
}
28+
return fab(n-1) + fab(n-2)
29+
}
30+
func TestFab(t *testing.T) {
31+
var r int
32+
r = fab(5)
33+
if r != 5 {
34+
t.Errorf("result is err, errResult: %d", r)
35+
}
36+
r = fab(6)
37+
if r != 8 {
38+
t.Errorf("result is err, errResult: %d", r)
39+
}
40+
r = fab(8)
41+
if r != 21 {
42+
t.Errorf("result is err, errResult: %d", r)
43+
}
44+
}
45+
46+
//第二种解法: 递归+记忆化
47+
//因为有重复的计算, 我们将其放入缓存中
48+
func fabCache(n int, cache map[int]int) int {
49+
if n <= 2 {
50+
return 1
51+
}
52+
if _, ok := cache[n]; !ok {
53+
cache[n] = fabCache(n-1, cache) + fabCache(n-2, cache)
54+
}
55+
return cache[n]
56+
}
57+
func TestFabCache(t *testing.T) {
58+
var r int
59+
cache := make(map[int]int)
60+
r = fabCache(5, cache)
61+
if r != 5 {
62+
t.Errorf("result is err, errResult: %d", r)
63+
}
64+
r = fabCache(6, cache)
65+
if r != 8 {
66+
t.Errorf("result is err, errResult: %d", r)
67+
}
68+
r = fabCache(8, cache)
69+
if r != 21 {
70+
t.Errorf("result is err, errResult: %d", r)
71+
}
72+
}
73+
74+
//第三种解法: 递推法
75+
//首先找出规律公式 f(n) = f(n-1) + f(n-2)
76+
func fabProgramming(n int) int {
77+
a, b := 0, 1
78+
for i := 0; i < n; i++ {
79+
a, b = b, a+b
80+
}
81+
return a
82+
}
83+
84+
func TestFabProgramming(t *testing.T) {
85+
var r int
86+
r = fabProgramming(5)
87+
if r != 5 {
88+
t.Errorf("result is err, errResult: %d", r)
89+
}
90+
r = fabProgramming(6)
91+
if r != 8 {
92+
t.Errorf("result is err, errResult: %d", r)
93+
}
94+
r = fabProgramming(8)
95+
if r != 21 {
96+
t.Errorf("result is err, errResult: %d", r)
97+
}
98+
}
99+
func fabProgramming2(n int) int {
100+
arr := make([]int, n+1)
101+
arr[0] = 0
102+
arr[1] = 1
103+
for i := 2; i <= n; i++ {
104+
arr[i] = arr[i-1] + arr[i-2]
105+
}
106+
return arr[n]
107+
}
108+
func TestFabProgramming2(t *testing.T) {
109+
var r int
110+
r = fabProgramming2(5)
111+
if r != 5 {
112+
t.Errorf("result is err, errResult: %d", r)
113+
}
114+
r = fabProgramming2(6)
115+
if r != 8 {
116+
t.Errorf("result is err, errResult: %d", r)
117+
}
118+
r = fabProgramming2(8)
119+
if r != 21 {
120+
t.Errorf("result is err, errResult: %d", r)
121+
}
122+
}

LeetCode/1/two_sum_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package leet_code_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
//https://leetcode-cn.com/problems/two-sum/
9+
10+
//题目意思是: 给定一个目标值,找出数组里2个数相加等于目标值的下标
11+
func TestFindTwoSum(t *testing.T) {
12+
list := []int{2, 3, 7, 8}
13+
a, b := FindTwoSum(list, 15)
14+
fmt.Println(a, b)
15+
}
16+
17+
//思路: 利用相减的结果,错位存储map, 也就是说把相减的结果做key存入map里,待下次相减的结果在map里找到,并返回
18+
func FindTwoSum(list []int, target int) (int, int) {
19+
checked := make(map[int]int)
20+
for i := 0; i < len(list); i++ {
21+
diff := target - list[i] //相减获取差值
22+
if _, ok := checked[diff]; ok { //判断是否存在map里
23+
return checked[diff], i //返回map的值,与当前i为下标
24+
}
25+
checked[list[i]] = i //将相减的结果做key存储.
26+
}
27+
return -1, -1
28+
}

base/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 什么时间和空间复杂度
1+
# 什么是时间和空间复杂度
22

33
# 时间复杂度
44
> 首先要说的是,时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数。
@@ -23,7 +23,7 @@
2323
- 如f(n)=2*n3+2n+100则O(n)=n3。
2424

2525
# 空间复杂度
26-
> 空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度
26+
> 空间复杂度是对一个算法在运行过程中临时占用存储空间大小的度量
2727
2828
### 计算方法:
2929
- ①忽略常数,用O(1)表示

base/base_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package base
2+
3+
import (
4+
"fmt"
5+
"math"
6+
"testing"
7+
)
8+
9+
func TestLog(t *testing.T) {
10+
fmt.Println(math.Log2(8))
11+
fmt.Println(math.Log2(128))
12+
fmt.Println(math.Log2(128 * 2))
13+
fmt.Println(math.Log2(1000000000))
14+
}

base/main.go

-11
This file was deleted.

base/max_common_divisor_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package base
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
//最大公约数
9+
func recursionCommonDivisor(a, b int) int {
10+
if b == 0 {
11+
return a
12+
}
13+
return recursionCommonDivisor(b, a%b)
14+
}
15+
func forCommonDivisor(a, b int) int {
16+
fmt.Printf("first:a:%d, b:%d \n", a, b)
17+
for b != 0 {
18+
ret := a % b
19+
a = b
20+
b = ret
21+
fmt.Printf("a:%d, b:%d,ret: %d\n", a, b, ret)
22+
}
23+
return a
24+
}
25+
func TestRecursionCommonDivisor(t *testing.T) {
26+
var a, b int
27+
a, b = 105, 24
28+
fmt.Println(recursionCommonDivisor(a, b))
29+
fmt.Println(forCommonDivisor(a, b))
30+
fmt.Println(forCommonDivisor(1680, 640))
31+
fmt.Println(105 % 24)
32+
fmt.Println(24 % 105)
33+
34+
}

bianry_search/binary_search_test.go

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package bianry_search
2+
3+
import (
4+
"testing"
5+
)
6+
7+
//二分查找
8+
//数组必须是有序的.否则免谈
9+
//每一次查找都是折半查找. 比对目标值, 四种情况, 如下:
10+
//第一种情况:相等则返回下标
11+
//第二种情况: 目标值小于中间值, 则修改high值,即high - 1
12+
//第三种情况: 目标值大于中间值, 则修改low值, 即low + 1
13+
//第四种情况: 未找到.返回 -1
14+
func binarySearch(arr []int, search int) int {
15+
low := 0 //定义最低位
16+
high := len(arr) - 1 //定义最高位, 即数组的最后的下标
17+
for low <= high { //缩小到只包含一个元素
18+
mid := (low + high) / 2
19+
if search == arr[mid] {
20+
return mid
21+
} else if search < arr[mid] {
22+
high = mid - 1
23+
} else if search > arr[mid] {
24+
low = mid + 1
25+
} else {
26+
return -1
27+
}
28+
}
29+
return -1
30+
}
31+
func TestBinarySearch(t *testing.T) {
32+
arr := []int{1, 3, 7, 9, 10, 22, 88}
33+
tests := []struct {
34+
name string
35+
args int
36+
want int
37+
}{
38+
{
39+
"二分查找1",
40+
1,
41+
0,
42+
},
43+
{
44+
"二分查找2",
45+
22,
46+
5,
47+
},
48+
{
49+
"二分查找3",
50+
100,
51+
-1,
52+
},
53+
}
54+
for _, item := range tests {
55+
t.Run(item.name, func(t *testing.T) {
56+
result := binarySearch(arr, item.args)
57+
if result != item.want {
58+
t.Errorf("want: %d, err:%d\n", item.want, result)
59+
}
60+
})
61+
}
62+
}

greedy/greedy_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package greedy
2+
3+
import (
4+
"fmt"
5+
"math"
6+
"testing"
7+
)
8+
9+
//贪心算法 对问题的求解,只做出当前的最好的选择
10+
11+
//找零钱 13
12+
func FindGreedy(v int) []int {
13+
a := []int{10, 8, 5, 3, 2, 1}
14+
result := make([]int, 0)
15+
for i := 0; i < len(a); i++ {
16+
cnt := math.Floor(float64(v) / float64(a[i]))
17+
if cnt > 0 && v > 0 && v >= a[i]*int(cnt) {
18+
v -= a[i] * int(cnt)
19+
for j := 0; j < int(cnt); j++ {
20+
result = append(result, a[i])
21+
}
22+
}
23+
}
24+
return result
25+
}
26+
func TestFindGreedy(t *testing.T) {
27+
s := FindGreedy(132)
28+
fmt.Println(s)
29+
}

0 commit comments

Comments
 (0)