【代码随想录——哈希表】

devtools/2024/10/18 18:15:42/

1.哈希表理论基础

首先什么是 哈希表,哈希表(英文名字为Hash table,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道都是指hash table就可以了)。
在这里插入图片描述
那么哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里。

哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

2. 有效的字母异位词

在这里插入图片描述

// 判断字符串 t 是否是字符串 s 的字母异位词
func isAnagram(s string, t string) bool {charCount := make(map[rune]int,0)// 若字符串长度不同,直接返回 falseif len(s) != len(t) {return false}// 将字符串转换为字符数组,并对字符数组进行排序sChars := []rune(s)tChars := []rune(t)for i:=0;i<len(sChars);i++{if _,ok:=charCount[sChars[i]];ok{charCount[sChars[i]]++}else{charCount[sChars[i]]=1}}for i:=0;i<len(tChars);i++{char,ok := charCount[tChars[i]]if !ok || char==0{return false}charCount[tChars[i]]--}return true
}

这是官方的一种更简洁的写法:

func isAnagram(s string, t string) bool {if len(s)!=len(t){return false}s_map:=[26]int{}t_map:=[26]int{}for i:=0;i<len(s);i++{s_map[s[i]-'a']++t_map[t[i]-'a']++}return s_map==t_map
}

2.1 字母异位词分组

在这里插入图片描述

2.1.1 第一次的写法,有点慢

func groupAnagrams(strs []string) [][]string {map_style := make([][26]int, 0)str_list := make([][]string, 0)map_index := 0for _, str := range strs {strMap := changeStrToMap(str)index := findCorrectStyle(strMap, map_style, map_index)if index == -1 {//表明这是一个新的stylemap_style = append(map_style, strMap)temp := []string{str}str_list = append(str_list, temp)map_index++} else {str_list[index] = append(str_list[index], str)}}return str_list[0:map_index]
}func changeStrToMap(s string) [26]int {s_map := [26]int{}for i := 0; i < len(s); i++ {s_map[s[i]-'a']++}return s_map
}func findCorrectStyle(strMap [26]int, map_style [][26]int, map_index int) int {for i := 0; i < map_index; i++ {if strMap == map_style[i] {return i}}return -1
}

2.1.2 学习一下高手的写法

确实快,主体思路没什么问题,就是不知道数组也能当做map的key。

func groupAnagrams(strs []string) [][]string {// 没想到数组也可以当做keyhmap := make(map[[26]int][]string)for _, str := range strs {// key 表示str 的字符最多26个,每个字符有多少个key := [26]int{}// 计数for _, ch := range str {// idx 代表字符距离小写字母的距离, b 的话是1idx := ch - 'a'key[idx] ++}hmap[key] = append(hmap[key], str)}result := make([][]string, 0, len(hmap))for _, v := range hmap {result = append(result, v)}   return result
}

2.2 找到字符串中所有字母异位词

在这里插入图片描述

func findAnagrams(s string, p string) []int {res := make([]int, 0)if len(s) < len(p) {return res}// 用来存储p中各个小写字母出现的次数pattern := [26]int{}temp := [26]int{}for i := 0; i < len(p); i++ {pattern[p[i]-'a']++temp[s[i]-'a']++}if pattern == temp {res = append(res, 0)}for i := 0; i < len(s)-len(p); i++ {temp[s[i]-'a']--temp[s[i+len(p)]-'a']++if pattern == temp {res = append(res, i+1)}}return res
}

3. 两个数组的交集

在这里插入图片描述

func intersection(nums1 []int, nums2 []int) []int {mp := make(map[int]struct{},0)res := make([]int,0)// 遍历nums1for _,num := range(nums1){mp[num] = struct{}{}}// 遍历nums2for _,num := range(nums2){_,ok := mp[num]if ok{// 查找到相同元素,加入答案。并从mp中删除res = append(res,num)delete(mp,num)}}return res
}

3.1 两个数组的交集②

在这里插入图片描述
和上面的代码只有一点点区别,区别在于这道题目需要记录元素出现的个数。

func intersect(nums1 []int, nums2 []int) []int {mp := make(map[int]int,0)res := make([]int,0)// 遍历nums1for _,num := range(nums1){_,ok := mp[num]if !ok{mp[num]=1}else{mp[num]++}}// 遍历nums2for _,num := range(nums2){_,ok := mp[num]if ok{// 查找到相同元素,加入答案。并从mp中删除res = append(res,num)mp[num]--if mp[num]==0{delete(mp,num)}}}return res
}

4.快乐数

在这里插入图片描述

func isHappy(n int) bool {mp := make(map[int]struct{},0)for n != 1{_,ok := mp[n]if ok {//这个数见过return false}//没见过,就记录一下mp[n] = struct{}{}n = getSum(n)}return true
}func getSum(n int)int{res := 0for n>0{res = res + (n%10)*(n%10)n = n/10}return res
}

5. 两数之和

在这里插入图片描述

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

6. 四数相加②

在这里插入图片描述
思路:两两组合

func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {res := 0mp := make(map[int]int,len(nums1)*len(nums1))//循环遍历nums1和nums2两个数组for i:=0;i<len(nums1);i++{for j:=0;j<len(nums2);j++{num := nums1[i] + nums2[j]if _,ok := mp[num];ok{mp[num]++}else{mp[num]=1}}}//循环遍历nums3和nums4两个数组for i:=0;i<len(nums3);i++{for j:=0;j<len(nums4);j++{num := nums3[i] + nums4[j]if _,ok := mp[-num];ok{res += mp[-num]}}}return res
}

7.赎金信

在这里插入图片描述

func canConstruct(ransomNote string, magazine string) bool {pattern1 := [26]int{}for i:=0;i<len(magazine);i++{pattern1[magazine[i]-'a']++}for i:=0;i<len(ransomNote);i++{pattern1[ransomNote[i]-'a']--if pattern1[ransomNote[i]-'a']<0{return false}}return true
}

8.三数之和

在这里插入图片描述
方法一:哈希表

这题不太适合使用hash来做

方法二:双指针,需要先排序。感觉不够快

func threeSum(nums []int) [][]int {var result [][]intif nums == nil || len(nums) < 3 {return result}slices.Sort(nums)for i := 0; i < len(nums); i++ {if nums[i] > 0 {return result}if i > 0 && nums[i] == nums[i-1] {continue}L := i + 1R := len(nums) - 1for L < R {if nums[i]+nums[L]+nums[R] == 0 {sub := []int{nums[i], nums[L], nums[R]}result = append(result, sub)for L < R && nums[L] == nums[L+1] {L += 1}for L < R && nums[R] == nums[R-1] {R -= 1}L += 1R -= 1}else if nums[i]+nums[L]+nums[R] > 0 {R -= 1} else {L += 1}}}return result
}

9.四数之和

在这里插入图片描述

9.1 利用map的写法

我的方法无法通过测试用例,会超时
在这里插入图片描述

func fourSum(nums []int, target int) [][]int {res := make(map[[4]int]struct{}, 0)mp := make(map[int][]int, 0)for i := 0; i < len(nums); i++ {for j := i + 1; j < len(nums); j++ {temp := nums[i] + nums[j]arr, ok := mp[temp]if !ok {slice := make([]int, 2)slice[0] = islice[1] = jmp[temp] = slice} else {//已有arr = append(arr, i)arr = append(arr, j)mp[temp] = arr}}}for key, arr1 := range mp {toFind := target - keyarr2, ok := mp[toFind]if !ok {continue}for i := 0; i < len(arr1)/2; i++ {for j := 0; j < len(arr2)/2; j++ {index_a, index_b := arr1[i*2], arr1[i*2+1]index_c, index_d := arr2[j*2], arr2[j*2+1]if index_a == index_c || index_a == index_d || index_b == index_c || index_b == index_d {continue}item := []int{nums[index_a], nums[index_b], nums[index_c], nums[index_d]}sort.Ints(item)res[[4]int{item[0], item[1], item[2], item[3]}] = struct{}{}}}}back := [][]int{}for key, _ := range res {back = append(back, key[:])}return back
}

9.2 使用双指针的解法

两层for循环,套用一个左右指针。可以通过剪枝提高算法的运行速度。

func fourSum(nums []int, target int) [][]int {if len(nums) < 4 {return nil}sort.Ints(nums)var res [][]intfor i := 0; i < len(nums)-3; i++ {n1 := nums[i]// if n1 > target { // 不能这样写,因为可能是负数// 	break// }if i > 0 && n1 == nums[i-1] {  // 对nums[i]去重continue}for j := i + 1; j < len(nums)-2; j++ {n2 := nums[j]if j > i+1 && n2 == nums[j-1] {  // 对nums[j]去重continue}l := j + 1r := len(nums) - 1for l < r {n3 := nums[l]n4 := nums[r]sum := n1 + n2 + n3 + n4if sum < target {l++} else if sum > target {r--} else {res = append(res, []int{n1, n2, n3, n4})for l < r && n3 == nums[l+1] { // 去重l++}for l < r && n4 == nums[r-1] { // 去重r--}// 找到答案时,双指针同时靠近r--l++}}}}return res
}

http://www.ppmy.cn/devtools/36358.html

相关文章

IIoT:数据融合在工业物联网中的应用——青创智通

工业物联网解决方案-工业IOT-青创智通 随着科技的不断发展&#xff0c;工业物联网&#xff08;IIoT&#xff09;已经逐渐渗透到各个行业&#xff0c;为企业的生产和管理带来了前所未有的便利。 然而&#xff0c;与此同时&#xff0c;海量的数据也为企业带来了挑战。如何将这些…

暗区突围联机不了联机失败无法联机的极速解决方法

暗区突围联机不了/联机失败/无法联机的极速解决方法 《暗区突围》是由腾讯魔方工作室群开发的第一人称射击类手游&#xff0c;于2021年8月17日进行先锋测试&#xff0c;并在2022年7月13日正式公测。《暗区突围》提供了双模式玩法&#xff0c;包括战术行动和伪装潜入&#…

C# Solidworks二次开发:枚举应用实战(第十三讲)

大家好&#xff0c;今天继续介绍我们的枚举应用系列。 下面是今天要介绍的枚举&#xff1a; &#xff08;1&#xff09;第一个为swsUserPreferenceIntegerValue_e&#xff0c;这个枚举的含义为用户偏好整数值&#xff0c;下面是官方的具体枚举值&#xff1a; MemberDescript…

R语言计算特定列的和(自备)

R语言长款数据转换&#xff08;自备&#xff09;_r语言宽数据转换成长数据-CSDN博客 数据 rm(list ls()) library(ggplot2) library(ggpubr) library(cowplot) data <- iris##鸢尾花数据集 #[1] "Sepal.Length" "Sepal.Width" "Petal.Length&…

FastAPI - Tortoise ORM 数据库基础操作

文章目录 1. 安装 Tortoise ORM2. 定义模型3. 初始化数据库连接4. 数据库操作4.1 创建数据4.2 查询数据4.3 更新数据4.4 删除数据 5. 使用 Pydantic 模型6. 关闭数据库连接7. fields类相关操作1. fields.IntField2. fields.BigIntField3. fields.SmallIntField4. fields.CharFi…

vue3—项目创建

背景 初次学习vue3&#xff0c;需要从项目创建开始。 步骤 打开cmd命令行&#xff0c;进入项目存放目录下&#xff0c;执行创建命令&#xff1a; npm create vuelatest 这一指令将会安装并执行 create-vue&#xff0c;它是 Vue 官方的项目脚手架工具。你将会看到一些诸如 …

浙里办开发相关问题

1.获取相册图片和拍照的方法 ZWJSBridge.chooseImage({upload: true,}).then((result) > {try {result.picPath.map((item) > {photoList.unshift(item)})} catch (error) {}}) 相关API import { createElement, useState } from rax; import View from rax-view; impo…

计算机毕业设计 | springboot+vue小米商城 米家购物网站管理系统

1&#xff0c;项目背景 国家大力推进信息化建设的大背景下&#xff0c;城市网络基础设施和信息化应用水平得到了极大的提高和提高。特别是在经济发达的沿海地区&#xff0c;商业和服务业也比较发达&#xff0c;公众接受新事物的能力和消费水平也比较高。开展商贸流通产业的信息…