11.代码随想录-哈希表(上)

哈希表理论基础

        定义

        哈希表(散列表hash table),存储键值对。

        这里建议大家去看一下map的底层实现,gomap的底层和redis中字典的实现方式是基本一致的。

        哈希碰撞

        两个key都映射到了一个哈希表上的同一个索引位置,就是hash碰撞。这里两种处理方式,gomap和redis都使用的拉链法,即哈希表上索引的节点是一个链表的头结点,所有key的哈希值映射到这个索引点的都成为这个链表上的节点。当然也可能出现某个链表上的节点过多导致效率降低的情况,这部分往下就的扩容相关的知识,面试go是需要掌握的。另外一种是线性探测法,需要tablesize大于datasize,把碰撞的元素放到下面,但是会产生聚集效果,比如1,2,3都有元素,下一个hash为1,2,3的都会放到4。然后为了解决这种现象导致的效率降低还有二次探测法等等。

有效的字母异位词

        题干:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

        测试地址:. - 力扣(LeetCode)        

        暴力循环可以解决,但是显然使用map非常简单。

func isAnagram(s string, t string) bool {
	record := [26]int{}
	for _, v := range s {
		record[v-'a']++
	}
	for _, r := range t {
		record[r-'a']--
	}
	return record == [26]int{}   
}

        第二种方法就只遍历一次字符串就可以了

func isAnagram(s string, t string) bool {
	if len(s) != len(t) {
		return false
	}
	records := [26]int{}
	for i := 0; i < len(s); i++ {
		if s[i] == t[i] {
			continue
		}
		sindex := s[i] - 'a'
		records[sindex]++
		tindex := t[i] - 'a'
		records[tindex]--
	}
	for _, record := range records {
		if record != 0 {
			return false
		}
	}
	return true
}

两个数组的交集

        题干:给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

        测试地址:. - 力扣(LeetCode)

func intersection(nums1 []int, nums2 []int) []int {
	numsmap1, numsmap2 := make(map[int]bool, 0), make(map[int]bool, 0)
	res := make([]int, 0)
	for _, v := range nums1 {
		numsmap1[v] = true
	}
	for _, v := range nums2 {
		if numsmap2[v] == false{
			numsmap2[v] = true
			if numsmap2[v] == true && numsmap1[v] == true {
				res = append(res, v)
			}
		}
	}
	return res
}

快乐数

        题干:编写一个算法来判断一个数 n 是不是快乐数。「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。如果 n 是快乐数就返回 True ;不是,则返回 False 。

        测试地址:. - 力扣(LeetCode)

        也很简单的一题,用来熟悉对map的使用挺好的。

func isHappy(n int) bool {
	num := make(map[int]bool, 0)
	for n != 1 && num[n] != true {
		num[n] = true
		n = getsum(n)
	}
	return n == 1
}

func getsum(n int) (sum int) {
	for n != 0 {
		sum = (n%10)*(n%10) + sum
		n /= 10
	}
	return sum
}

两数之和

        题干:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

        测试地址:. - 力扣(LeetCode)

        最简单的题了,梦开始的地方。这里利用map直接查询的特点可以直接去寻找我们想要的值。

func twoSum(nums []int, target int) []int {
	m := make(map[int]int)
    for i, v := range nums {
        j, ok := m[target-v]
        if ok {
            return []int{j, i}
        }
        m[v] = i
    }
    return nil
}

        

### 关于哈希表的学习资源 对于希望深入理解哈希表的人来说,代码随想录提供了丰富的学习材料。网站上的哈希表部分不仅涵盖了基础概念,还包含了实际应用案例和解题思路[^1]。 #### 哈希表的基础理论 哈希表是一种基于键值对的数据结构,它允许快速访问数据项。其工作原理是通过特定的哈希函数计算给定键对应的索引位置,并以此来存取关联的数据值。当多个不同的输入映射到相同的输出时会发生冲突,即所谓的哈希碰撞现象。处理这类情况的方法有两种主要方式:拉链法(分离链接)与开放寻址法(如线性探测)。这些基础知识可以在代码随想录有关哈希表的文章中找到详细的解释[^5]。 #### 实战练习与技巧分享 为了更好地掌握哈希表的应用场景和技术细节,在完成理论学习之后可以尝试解答一些经典的算法题目。例如,“有效的字母异位词”,这是一道考察字符串操作能力的好题;还有“快乐数”的求解过程也涉及到循环检测等内容。此外,《学透哈希表》系列课程则更侧重于指导如何高效利用`Map`接口下的各种方法解决问题,比如`getOrDefault()`等实用功能[^4]。 ```java // 使用HashMap.getOrDefault()获取指定key对应value,如果不存在返回默认值 public int getValueOrDefault(Map<String, Integer> map, String key){ return map.getOrDefault(key, 0); } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值