Go 语言算法常用库函数

时至今日已经用 Go 刷了大半年的算法了,对于大部分题型都做过了,因为我一直保持着网页没有语法提示的情况下进行刷算法,所以有些必须记在脑子里才能在关键时刻用出来,趁此机会总结回顾一下 Go 语言算法常用库函数。

常量

最大值和最小值(其他不同于 int 的常量同理)

math.MaxInt , math.MinInt

排序

(这部分慎用,很多直接考排序的算法在面试的时候是肯定不允许使用的,在一些排序不是重点的题里面可以用,比如合并数组)

sort.Sort(data Interface)

//需要实现以下方法:
Len() int 
Less(i int, j int) bool 
Swap(i int, j int)
sort.Ints(a []int)

//Ints函数将a排序为递增顺序。
sort.Strings(a []string)

//Strings函数将a排序为递增顺序。
func SearchInts(a []int, x int) int

//SearchInts在递增顺序的a中搜索x,返回x的索引。如果查找不到,返回值是x应该插入a的位置(以保证a的递增顺序),返回值可以是len(a)。
func SearchStrings(a []int, x int) int

//SearchStrings在递增顺序的a中搜索x,返回x的索引。如果查找不到,返回值是x应该插入a的位置(以保证a的递增顺序),返回值可以是len(a)。
// 个人用的最多
func Slice(x any, less func(i int, j int) bool)

people := []struct {     
    Name string     
    Age  int 
}{ {"Gopher", 7}, {"Alice", 55}, {"Vera", 24},{"Bob", 75}, } 


sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name }

数据结构

链表

直接考链表的算法题用不着官方库,也不能用,但是例如 LRU 算法中使用官方实现的链表就会减轻我们的负担

创建链表

l := list.New()

list包实现了双向链表。要遍历一个链表:

for e := l.Front(); e != nil; e = e.Next() {
        // do something with e.Value
}

获取链表长度

func (l *List) Len() int

获取链表第一个元素

func (l *List) Front() *Element

获取链表最后一个元素

func (l *List) Back() *Element

PushFront将一个值为v的新元素插入链表的第一个位置,返回生成的新元素。

func (l *List) PushFront(v interface{}) *Element

PushBack将一个值为v的新元素插入链表的最后一个位置,返回生成的新元素。

func (l *List) PushBack(v interface{}) *Element

MoveToFront将元素e移动到链表的第一个位置,如果e不是l的元素,l不会被修改。

func (l *List) MoveToFront(e *Element)

MoveToBack将元素e移动到链表的最后一个位置,如果e不是l的元素,l不会被修改。

func (l *List) MoveToBack(e *Element)

Remove删除链表中的元素e,并返回e.Value。

func (l *List) Remove(e *Element) interface{}

在获取xx中第k大/小的算法题用的很多,当然如果你能手撕堆排序那就很强了

堆的初始化:

heap包提供了对任意类型(实现了heap.Interface接口)的堆操作。(最小)堆是具有“每个节点都是以其为根的子树中最小值”属性的树。

树的最小元素为其根元素,索引0的位置。

heap是常用的实现优先队列的方法。要创建一个优先队列,实现一个具有使用(负的)优先级作为比较的依据的Less方法的Heap接口,如此一来可用Push添加项目而用Pop取出队列最高优先级的项目。

type Interface interface{
    sort.Interface
    Push(x interface{}) // 向末尾添加元素
    Pop() interface{}   // 从末尾删除元素   
}

//sort.Interface
type Interface interface{
    // Len方法返回集合中的元素个数      
    Len() int
    // Less方法报告索引i的元素是否比索引j的元素小
    Less(i, j int) bool
    // Swap方法交换索引i和j的两个元素
    Swap(i, j int)    
}

需要实现以上5个方法

向堆h中插入元素x,并保持堆的约束性。复杂度O(log(n)),其中n等于h.Len()。

func Push(h Interface, x interface{})

删除并返回堆h中的最小元素(不影响约束性)。复杂度O(log(n)),其中n等于h.Len()。等价于Remove(h, 0)。

func Pop(h Interface) interface{}

删除堆中的第i个元素,并保持堆的约束性。复杂度O(log(n)),其中n等于h.Len()。

func Remove(h Interface, i int) interface{}

在修改第i个元素后,调用本函数修复堆,比删除第i个元素后插入新元素更有效率。

func Fix(h Interface, i int)

基本没用过,就不说了

字符串

strings 包

常见的比如 split、join 就不说了

判断字符串s是否包含子串substr。(考KMP但是你不幸地忘记的时候可以用这个函数)

func Contains(s, substr string) bool

子串sep在字符串s中第一次出现的位置,不存在则返回-1。

func Index(s, sep string) int

s中第一个满足函数f的位置i(该处的utf-8码值r满足f(r)==true),不存在则返回-1。

func IndexFunc(s string, f func(rune) bool) int

strconv 包

用的多的就两个吧,其他的强转一般也能搞定

func ParseInt(s string, base int, bitSize int) (i int64, err error)
func Atoi(s string) (i int, err error)