边做算法边学go语言之LeetCode1160:拼写单词

简介: 边做算法边学go语言之LeetCode1160:拼写单词

aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzIwMjAtMDMtMDctMTQwNzE1LmpwZw.png

前言

本系列文章为《leetcode》刷题笔记。

题目位置:拼写单词

题集:LeetCode

项目位置:我的Github项目


题目


给你一份『词汇表』(字符串数组words 和一张『字母表』(字符串) chars

假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。


注意:每次拼写时,chars 中的每个字母都只能用一次。

返回词汇表 words 中你掌握的所有单词的 长度之和。

示例 1:

输入:words = ["cat","bt","hat","tree"], chars = "atach"
输出:6
解释: 
可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6。


示例 2:


输入:words = ["hello","world","leetcode"], chars = "welldonehoneyr"
输出:10
解释:
可以形成字符串 "hello" 和 "world",所以答案是 5 + 5 = 10。


提示:


1 <= words.length <= 1000
1 <= words[i].length, chars.length <= 100


所有字符串中都仅包含小写英文字母


思路


aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzU0NWJlMzMxMzk2NzdlNWVmOGRlNTI3MjU1YzkzZDExYjIxZmZjNzdhMDIwZjIyY2FiZWMyNzc5Zjk1ZTA0MTUuZ2lm.gif


aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzU0NWJlMzMxMzk2NzdlNWVmOGRlNTI3MjU1YzkzZDExYjIxZmZjNzdhMDIwZjIyY2FiZWMyNzc5Zjk1ZTA0MTUuZ2lm.gif

如上图,这是一题hash table的题目,非常简单,先用一个map统计chars中的字母数量,然后遍历给的字符串数组,逐个统计,对比即可。

统计chars中的字母数量(int类型自动初始化为0)


cmap := make(map[uint8]int)
  for i := 0; i < len(chars); i++ {
    cmap[chars[i]] ++
  }

遍历单词集合

for i := 0; i < len(words); i++ {


map拷贝(原理是序列化成json,再反序列化回来)

ExtractInto(cmap, &tmpMap)



遍历单词中的每个字母, 只要没在chars的字典中出现就判断失败,一旦出现就让当前字符字典数量--

j := 0
    for ; j < len(words[i]); j++ {
      if tmpMap[words[i][j]] <= 0 {
        break
      }
      tmpMap[words[i][j]] --
    }

如果j等于了当前单词长度,说明所有字母都包含在里面,就统计上。


if j == len(words[i]) {
      count += len(words[i])
    }


可惜啊。。


aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzIwMjAtMDMtMTctMTc0NDEyLnBuZw.png


估计是map本身寻找hash位置耗时,以及map拷贝耗时优化一下代码,把map转换成数组。

长度为26个字母,下标就是0-25,也就是a-a到z-a。

aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzIwMjAtMDMtMTgtMDUxNjE3LmpwZw.png


详细代码如下一节优化后。


代码


优化前

Go


func countCharacters(words []string, chars string) int {
  cmap := make(map[uint8]int)
  for i := 0; i < len(chars); i++ {
    cmap[chars[i]] ++
  }
  count := 0
  tmpMap := make(map[uint8]int)
  for i := 0; i < len(words); i++ {
    ExtractInto(cmap, &tmpMap)
    j := 0
    for ; j < len(words[i]); j++ {
      if tmpMap[words[i][j]] <= 0 {
        break
      }
      tmpMap[words[i][j]] --
    }
    if j == len(words[i]) {
      count += len(words[i])
    }
  }
  return count
}
/*
  把interface类型转换成我们想要的struct类型
  这个通用方法可以转换成任意一个想要的类型
 */
func ExtractInto(source interface{}, to interface{}) error {
  b, err := json.Marshal(source)
  if err != nil {
    return err
  }
  err = json.Unmarshal(b, to)
  return err
}

优化后

Go

//优化后
func countCharacters(words []string, chars string) int {
  var byteCount [26]int
  for _, char := range chars {
    byteCount[char-'a']++
  }
  ret := 0
  for _, word := range words {
    bc, match := byteCount, true
    for _, char := range word {
      if bc[char-'a'] <= 0 {
        match = false
        break
      }
      bc[char-'a']--
    }
    if match {
      ret += len(word)
    }
  }
  return ret
}


相关文章
|
27天前
|
存储 监控 算法
防止员工泄密软件中文件访问日志管理的 Go 语言 B + 树算法
B+树凭借高效范围查询与稳定插入删除性能,为防止员工泄密软件提供高响应、可追溯的日志管理方案,显著提升海量文件操作日志的存储与检索效率。
69 2
|
24天前
|
存储 监控 算法
基于 Go 语言跳表结构的局域网控制桌面软件进程管理算法研究
针对企业局域网控制桌面软件对海量进程实时监控的需求,本文提出基于跳表的高效管理方案。通过多级索引实现O(log n)的查询、插入与删除性能,结合Go语言实现并发安全的跳表结构,显著提升进程状态处理效率,适用于千级进程的毫秒级响应场景。
115 15
|
1月前
|
存储 缓存 算法
如何管理员工上网:基于 Go 语言实现的布隆过滤器访问拦截算法应用
布隆过滤器以空间换时间,通过多哈希函数实现黑名单的高效存储与毫秒级检索,解决传统方案内存占用大、响应慢等问题,助力企业低成本、高效率管理员工上网行为。
109 3
|
1月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
124 1
|
2月前
|
存储 监控 算法
企业电脑监控系统中基于 Go 语言的跳表结构设备数据索引算法研究
本文介绍基于Go语言的跳表算法在企业电脑监控系统中的应用,通过多层索引结构将数据查询、插入、删除操作优化至O(log n),显著提升海量设备数据管理效率,解决传统链表查询延迟问题,实现高效设备状态定位与异常筛选。
104 3
|
29天前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
3月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
275 1
|
4月前
|
搜索推荐 算法 Go
Go语言数组排序(冒泡排序法)—— 用最直观的方式掌握排序算法
本案例介绍使用冒泡排序对整数数组进行升序排序的实现方法,涵盖输入处理、错误检查与排序逻辑。通过代码演示和算法解析,帮助理解排序原理及Go语言切片操作,为学习更复杂排序算法打下基础。
|
3月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
346 0
|
3月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
221 0

热门文章

最新文章