跟着算法学GO(7)

129 阅读3分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

生命不息,学习不止

题外话

大年初二啦,冬奥会也越来越近了,虽然昨晚的国足发挥的不好,但是,今天们还有冰壶的比赛可以看,我们要对生活充满希望,跟要对祖国健儿们充满希望!

image.png

废话不多说,上货

在这里插入图片描述

LeetcCode-3

无重复字符的最长子串

题目如下:

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

还是这道题,因为还有知识点呢

go实现算法

func lengthOfLongestSubstring(s string) int {
	strmap := make(map[byte]int)

	count := 0
	for i, j := 0, 0; j < len(s); j++ {
		if val, ok := strmap[s[j]]; ok {
			i = max(val, i)
		}
		count = max(count, j-i+1)
		strmap[s[j]] = j + 1   //添加元素
	}
	return count
}

func max(x, y int) int {
	if x > y {
		return x
	} else {
		return y
	}
}

小问题回顾

小问题:元素存放的流程是怎样的?几个变量间如何关联?

上回已经说了map几个核心的变量定义,这次就说说map使用过程中这几个核心变量具体参与了什么?

Map的实现机制

image.png

还是需要这张图的

一般我们常用两种方式来声明map,一种是算法实现中这种,通过make函数声明一个map

strmap := make(map[byte]int)

此时自动创建且初始化了map,此时map为空

另一种则是使用映射字面量来创建并初始化map

strmap := map[string]string{"Red:"#da1337","Orange":"#e95a22"}

我们下面就举个例子,假设一个map的hmap.B为2

也就意味着这个map拥有bucket的大小为2,而hmap.buckets长度是2^B为2.元素经过哈希运算后会落到某个bucket中进行存储,大概储存方式如下,

image.png

上图中的bucket0是地址,指向对应的(bucket)bmap,如下

image.png

每个bucket可以存储8个键值对。

tophash是个长度为8的数组,哈希值相同的键(准确的说是哈希值低位相同的键)存入当前bucket时会将哈希值的高位存储在该数组中,以方便后续匹配。

data区存放的是key-value数据,存放顺序是key/key/key/...value/value/value,如此存放是为了节省字节对齐带来的空间浪费。

type bmap struct {
    tophash [8]uint8 //存储哈希值的高8位
    data    byte[1]  //key value数据:key/key/key/.../value/value/value...
    overflow *bmap   //溢出bucket的地址
}

完整的存放形式如下

image.png

overflow 指针指向的是下一个bucket,据此将所有冲突的键连接起来。

也就是 * bucket

注意:上述中data和overflow并不是在结构体中显示定义的,源码中并未展示,而是直接通过指针运算进行访问的,为了方便大家理解,我手动写的。

这样这写主要的变量就已经成功的串联了起来

你以为结束了

小问题:什么是负载因子?负载因子有什么作用?扩容机制是怎样的?

下一篇就讲,敬请期待

在这里插入图片描述

大家看完发现有什么错误,写在下面吧!跟我黑虎阿福比划比划! 在这里插入图片描述