算法刷题之二字典

1|0字典类算法


字典所涉及到的题目有如下:

  1. 两数之和
  2. 字母异位词分组
  3. 数独
  4. 设计LRU

字典使用技巧:
字典在某些场景下很方便:

  1. 判断重复,某一个元素是否重复出现
  2. in操作的时间复杂度为常数
  3. 需要使用复杂数据结构,key-->[]
  4. 消灭判断,使用key直接获取value

2|0两数之和


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

给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

方法:
常规思路是可以两次循环找到数组中任意两个不重复元素的和,时间复杂度为O(2)。
高效的做法是将两个数相加等于target,变成判断b --> target-a 在不在字典中。如果在就说明有a + b 等于 target。同时,判断b在不在字典中是常数级别的操作,所以将两层循环变成一层循环。
知识点:使用了字典的查找高效这一特点

def twoSum(nums, target): hashmap={} for i,num in enumerate(nums): if hashmap.get(target - num) is not None: return [i,hashmap.get(target - num)] hashmap[num] = i #这句不能放在if语句之前,解决list中有重复值或target-num=num的情况

3|0字母异位词分组


题目:
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:

[ ["ate","eat","tea"], ["nat","tan"], ["bat"] ]

说明:
所有输入均为小写字母。
不考虑答案输出的顺序。

方法:给出的字符串数组,将每一个字符串重新排列之后可以分成三类。进一步说就是将排序之后相同的字符串加入到一个数组中。使用字典的key:value。value为数组,这样的结构能够完成,key就是排序后的字符串。因为排序之后的字符串是数组,所以不能直接作为key值,将其合并成字符串。
知识点: 字典的复杂格式 key:[]的使用。要熟练使用collections中的基础数据增强功能

def groupAnagrams(self, strs: List[str]) -> List[List[str]]: from collections import defaultdict # 构造一个key --> []的数据结构 strs_dict = defaultdict(list) for i in strs: strs_dict[''.join(sorted(i))].append(i) return list(strs_dict.values())

4|0有效的数独


题目:

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

上图是一个部分填充的有效的数独。
数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:
输入:

[ ["5","3",".",".","7",".",".",".","."], ["6",".",".","1","9","5",".",".","."], [".","9","8",".",".",".",".","6","."], ["8",".",".",".","6",".",".",".","3"], ["4",".",".","8",".","3",".",".","1"], ["7",".",".",".","2",".",".",".","6"], [".","6",".",".",".",".","2","8","."], [".",".",".","4","1","9",".",".","5"], [".",".",".",".","8",".",".","7","9"] ] 输出: true

方法:关键点在于判断当前的数字在同行、同列、同一个区域有没有重复。将每一个行中数字保存为一个字典,key是数字,value是出现次数。如果有重复,则value会大于1。同样,每一个列,每一个区域都需要以数字为key,建立字典。最后判断行、列、区域中哪一块有value大于1,则表明数独不存在

知识点:使用字典判断重复,比起循环查找要高效很多。同时字典不断添加还有一个先后循序,有些场合可以避免重复(两数之和)

def isValidSudoku(self, board): """ :type board: List[List[str]] :rtype: bool """ # init data rows = [{} for i in range(9)] columns = [{} for i in range(9)] boxes = [{} for i in range(9)] # validate a board for i in range(9): for j in range(9): num = board[i][j] if num != '.': num = int(num) box_index = (i // 3 ) * 3 + j // 3 # keep the current cell value rows[i][num] = rows[i].get(num, 0) + 1 columns[j][num] = columns[j].get(num, 0) + 1 boxes[box_index][num] = boxes[box_index].get(num, 0) + 1 # check if this value has been already seen before if rows[i][num] > 1 or columns[j][num] > 1 or boxes[box_index][num] > 1: return False return True

5|0设计LRU


题目:
设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能
set(key, value):将记录(key, value)插入该结构
get(key):返回key对应的value值

要求:

  1. set和get方法的时间复杂度为O(1)
  2. 某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的。
  3. 当缓存的大小超过K时,移除最不经常使用的记录,即set或get最久远的。

若opt=1,接下来两个整数x, y,表示set(x, y)
若opt=2,接下来一个整数x,表示get(x),若x未出现过或已被移除,则返回-1

对于每个操作2,输出一个答案

方法:题目中要求set或get的时间复杂度是O(1),这就是意味着添加或者查询元素是不能使用循环,所以必须是字典的数据结构。而set或get某一个元素同时还要让该元素热点最大,结合时间复杂度来考虑就不能用循环解决,只能用插入的顺序。但是总所周知通常字典是一个无序的,所以这里要使用有序字典。从collections中导入OrderedDict这种有序字典。有序字典顾名思义就是能够按照插入的顺序保存元素。
知识点:collections中增强数据结构,结合对时间复杂的要求

# # lru design # @param operators int整型二维数组 the ops # @param k int整型 the k # @return int整型一维数组 # class Solution: def LRU(self , operators , k ): from collections import OrderedDict res = [] dic = OrderedDict() for item in operators: oper = item[0] if oper == 1: key = item[1] value = item[2] if key in dic: dic.pop(key) else: if k > 0: k -= 1 else: dic.popitem(False) dic[key] = value elif oper == 2: key = item[1] res.append(dic.get(key, -1)) if key in dic: dic.move_to_end(key) return res

6|0总结


字典在算法中出镜的频率很高,这和字典本身的高效性能有关。通常来说一个题如果有一下特征,可以考虑使用字典来解决:

  1. 相加之和等于多少
  2. 判断元素是否重复出现
  3. 对元素分类操作

__EOF__

本文作者goldsunshine
本文链接https://www.cnblogs.com/goldsunshine/p/14921298.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   金色旭光  阅读(167)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示