TAG

哈希表

4 篇文章

题解-找出叠涂元素-哈希表,两种思路,在途中检查和在最后检查

Problem: 2661. 找出叠涂元素 思路:中途检查 解法 数据量不大,看着可以在每次涂色时候查询是否合法 但是每次都查询显然会超时,我们选择一个更有效的优化 已经说明各个数各不相同,不会出现一个格子被涂两遍的情况 我们用数组来记录每一行和每一列已经被涂的格子数量,就能知道这一行列是否被全涂满 时间复杂度: $O(m*n)$ 空间复杂度: $O(m*n)$ Code class Solution: def firstCompleteIndex(self, arr: List[int], mat: List[List[int]]) -> int: matMap={} m=len(mat) n=len(mat[0]) row=[0]*m col=[0]*n for i in range(m): for j in range(n): matMap[mat[i][j]]=(i,j) for index in range(len(arr)): num=arr[index] x,y=matMap[num] row[x]+=1 col[y]+=1 if row[x]==n or col[y]==m: return index return -1 思路:最后查询 解法 我们注意到当我们知道某一行的所有元素的时候,变相知道了这一行会被什么时候涂满,既这一行存在arr中最靠后的那个索引 所以我们的任务变成了寻找最先被涂满的行或者列 对arr进行hash,记录每个元素的具体位置,再遍历行列,在遍历过程中 行列取最大值表示让这一行填满最少需要的步数 res取上述的数的最小值 时间复杂度: $O(mn)$ 空间复杂度: $O(mn)$ Code class Solution { public: int firstCompleteIndex(vector<int>& arr, vector<vector<int>>& mat) { int res=arr.size(); unordered_map<int,int>hash; for (int i=0;i<arr.size();i++){ hash[arr[i]]=i; } for (int i=0;i<mat.size();i++){ int tmp=0; for (int j=0;j<mat[0].size();j++){ tmp=max(tmp,hash[mat[i][j]]); } res=min(res,tmp); } for (int j=0;j<mat[0].size();j++){ int tmp=0; for (int i=0;i<mat.size();i++){ tmp=max(tmp,hash[mat[i][j]]); } res=min(res,tmp); } return res; } }; class Solution: def firstCompleteIndex(self, arr: List[int], mat: List[List[int]]) -> int: res=len(arr) m=len(mat) n=len(mat[0]) arrLocation={} for i,a in enumerate(arr): arrLocation[a]=i for i in range(m): nowColNeedSteps=0 for j in range(n): nowColNeedSteps=max(nowColNeedSteps,arrLocation[mat[i][j]]) res=min(res,nowColNeedSteps) for j in range(n): nowRowNeedSteps=0 for i in range(m): nowRowNeedSteps=max(nowRowNeedSteps,arrLocation[mat[i][j]]) res=min(res,nowRowNeedSteps) return res

↗

题解-移位字符串分组-哈希表

Problem: 249. 移位字符串分组 思路 类似于凯撒密码的归类方式,我们将所有能通过轮转得到的字符串放在一起,不难想到可以通过暴力来对每一个字符串匹配 对于字符串仔细观察可以发现每一个可以归类到一起的字符串的本质是相同的,不只是字符串长度,还有与左右字母之间的差值 综上,对于每一类字符串我们只需要将其转化为模板的样子就能判断是否能归类 我们的问题就是如何将字符转成一个标准的模板 考虑字符之间的相对关系, 我们设首位为0,后面的每一位对应的是字符串该位与前一位的差 如果小于0则加26,来保证模式字符串相等 解题方法 对于每一个字符串,计算其相对字符的模板字符串 查询哈希表,如果有则插入到相对的答案组中 没有就新开一个答案组 重复上述操作 复杂度 时间复杂度: 只遍历一次 $O(mn)$,m为字符串长度 空间复杂度: 运用了哈希表 $O(n)$ Code class Solution { public: vector<vector<string>> groupStrings(vector<string>& strings) { vector<vector<string>>res; unordered_map<string,int>hash;//模板字符串及其对应的在答案的行数 for (auto &iter:strings){ string tmp="0_"; char a=iter[0]; int now; for (int i=1;i<iter.size();i++){ now=iter[i]-a; if (now<0)//保证模板的一致性 now+=26; tmp+=to_string(now)+"_"; a=iter[i]; } if (hash.find(tmp)!=hash.end()){ res[hash[tmp]].emplace_back(iter); } else{ hash[tmp]=res.size(); res.emplace_back(vector<string>(1,iter)); } } return res; } };

↗