IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Task12:哈希表 -> 正文阅读

[数据结构与算法]Task12:哈希表

1. 视频题目

1.1 存在重复元素

1.1.1 描述

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

示例 1:

输入:nums = [1,2,3,1]
输出:true

示例 2:

输入:nums = [1,2,3,4]
输出:false

示例 3:

输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true

提示:

1 <= nums.length <= 105
-109 <= nums[i] <= 109

1.1.2 代码

直接用一个哈希表记录已经访问过的数值即可

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        num_dic = dict()
        for i in nums:
            if i in num_dic:
                return True
            else:
                num_dic[i] = i
        return False

1.1.3 总结

直接查in dict,相当于查in dict.keys(),还是查的键

1.2 有效的数独

1.2.1 描述

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

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

注意:

一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用 ‘.’ 表示。

示例 1:

在这里插入图片描述

输入:board =
[[“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

示例 2:

输入:board =
[[“8”,“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”]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

提示:

board.length == 9
board[i].length == 9
board[i][j] 是一位数字(1-9)或者 ‘.’

1.2.2 代码

9个行字典,9个列字典,9个方块字典

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        row_dic = [{} for _ in range(9)]
        col_dic = [{} for _ in range(9)]
        box_dic = [{} for _ in range(9)]
        
        for row in range(9):
            for col in range(9):
                box = (row//3)*3 + (col//3)
                num = board[row][col]
                if num != '.':
                    if (num in row_dic[row]) or (num in col_dic[col]) or (num in box_dic[box]):
                        return False
                    else:
                        row_dic[row][num]=num
                        col_dic[col][num]=num
                        box_dic[box][num]=num
        return True

1.2.3 总结

可以用{}初始化字典,要注意去除空白格,需推导方块字典的编号

2. 视频题目

2.1 存在重复元素 II

2.1.1 描述

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [1,2,3,1], k = 3
输出:true

示例 2:

输入:nums = [1,0,1,1], k = 1
输出:true

示例 3:

输入:nums = [1,2,3,1,2,3], k = 2
输出:false

提示:

1 <= nums.length <= 105
-109 <= nums[i] <= 109
0 <= k <= 105

2.1.2 代码

这个题属于之前的进阶,要求指定范围k以内有重复的数字

所以说维护一个长为k+1的滑动窗口,窗口内各数字的距离均小于等于k

class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        tail = 0
        dic = {}
        while (tail < len(nums)) and (tail < k+1) :
            if nums[tail] in dic:
                return True
            else:
                dic[nums[tail]] = nums[tail]
            tail += 1
        head = 0
        while tail<len(nums):
            dic.pop(nums[head])
            if nums[tail] in dic:
                return True
            else:
                dic[nums[tail]] = nums[tail]
            head += 1
            tail += 1
        return False

2.1.3 总结

长为k+1的滑动窗口,窗口内各数字的距离均小于等于k

字典删除的方法为.pop(),但是必须给出key,默认删除最后一对的是popitem()

2.2 宝石与石头

2.2.1 描述

给你一个字符串 jewels 代表石头中宝石的类型,另有一个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

字母区分大小写,因此 “a” 和 “A” 是不同类型的石头。

示例 1:

输入:jewels = “aA”, stones = “aAAbbbb”
输出:3

示例 2:

输入:jewels = “z”, stones = “ZZ”
输出:0

提示:

1 <= jewels.length, stones.length <= 50
jewels 和 stones 仅由英文字母组成
jewels 中的所有字符都是 唯一的

2.2.2 代码

遍历宝石初始化字典,再遍历石头计数即可

class Solution:
    def numJewelsInStones(self, jewels: str, stones: str) -> int:
        dic = {}
        for item in jewels:
            dic[item] = 0
        for item in stones:
            if item in dic:
                dic[item] += 1
        return sum(dic.values())

2.2.3 总结

可调用API求和

2.3 子域名访问计数

2.3.1 描述

网站域名 “discuss.leetcode.com” 由多个子域名组成。顶级域名为 “com” ,二级域名为 “leetcode.com” ,最低一级为 “discuss.leetcode.com” 。当访问域名 “discuss.leetcode.com” 时,同时也会隐式访问其父域名 “leetcode.com” 以及 “com” 。

计数配对域名 是遵循 “rep d1.d2.d3” 或 “rep d1.d2” 格式的一个域名表示,其中 rep 表示访问域名的次数,d1.d2.d3 为域名本身。

例如,“9001 discuss.leetcode.com” 就是一个 计数配对域名 ,表示 discuss.leetcode.com 被访问了 9001 次。
给你一个 计数配对域名 组成的数组 cpdomains ,解析得到输入中每个子域名对应的 计数配对域名 ,并以数组形式返回。可以按 任意顺序 返回答案。

示例 1:

输入:cpdomains = [“9001 discuss.leetcode.com”]
输出:[“9001 leetcode.com”,“9001 discuss.leetcode.com”,“9001 com”]
解释:例子中仅包含一个网站域名:“discuss.leetcode.com”。
按照前文描述,子域名 “leetcode.com” 和 “com” 都会被访问,所以它们都被访问了 9001 次。

示例 2:

输入:cpdomains = [“900 google.mail.com”, “50 yahoo.com”, “1 intel.mail.com”, “5 wiki.org”]
输出:[“901 mail.com”,“50 yahoo.com”,“900 google.mail.com”,“5 wiki.org”,“5 org”,“1 intel.mail.com”,“951 com”]
解释:按照前文描述,会访问 “google.mail.com” 900 次,“yahoo.com” 50 次,“intel.mail.com” 1 次,“wiki.org” 5 次。
而对于父域名,会访问 “mail.com” 900 + 1 = 901 次,“com” 900 + 50 + 1 = 951 次,和 “org” 5 次。

提示:

1 <= cpdomain.length <= 100
1 <= cpdomain[i].length <= 100
cpdomain[i] 会遵循 “repi d1i.d2i.d3i” 或 “repi d1i.d2i” 格式
repi 是范围 [1, 104] 内的一个整数
d1i、d2i 和 d3i 由小写英文字母组成

2.3.2 代码

域名最长有3段,所以最多做两次分割,加上完整域名的访问,应该是三次遍历

第一次记录完整的域名,及其对应的访问次数,根据空格分割,写入字典当中

第二次根据上一次的字典的键值,也就是上一次的域名,使用.分割一次

如果分割结果长度大于1,也就是存在.,就得出上一级的域名,并记录域名及其对应次数

第三次也是根据上一次的字典的键值,也就是上一次的域名,使用.分割一次

如果分割结果长度大于1,也就是存在.,就再继续得出上一级的域名,并记录域名及其对应次数

因为此次遍历的是dic2的键值,所以我们可以顺便将其合并到dic1当中

如果dic1有这个键值,那就加上对应次数,如果没有就新建键值并赋予次数

域名最多只有3级,所以说最多使用.分割两次就足够了

接下来只需要再遍历一遍dic3,将其合并到dic1,就可以拼接结果返回了

为什么需要合并呢?是因为输入的域名当中可能同时包含二级和三级域名

举例如题目当中给出的数据:["900 google.mail.com", "50 yahoo.com"]

第一次遍历就不说了,第二次遍历第一次分割的时候,"50 yahoo.com"就出现了com

也就是说,com这个一级域名,已经出现在了dic2当中

而当第三次遍历第二次分割的时候,"900 google.mail.com"又一次出现了com

也就是说,com这个一级域名,再次出现在了dic3当中

所以说,dic1dic2dic3之中都有可能存在重复,所以需要合并访问数量再返回

class Solution:
    def subdomainVisits(self, cpdomains: List[str]) -> List[str]:
        dic1 = {}
        dic2 = {}
        dic3 = {}
        for item in cpdomains:
            raw = item.split(" ")
            if raw[1] in dic1:
                dic1[raw[1]] += int(raw[0])
            else:
                dic1[raw[1]] = int(raw[0])
        for item in dic1.keys():
            raw = item.split(".",1)
            if len(raw)>1:
                if raw[1] in dic2:
                    dic2[raw[1]] += dic1[item]
                else:
                    dic2[raw[1]] = dic1[item]
        for item in dic2.keys():
            raw = item.split(".",1)
            if len(raw)>1:
                if raw[1] in dic3:
                    dic3[raw[1]] += dic2[item]
                else:
                    dic3[raw[1]] = dic2[item]
            if item in dic1:
                dic1[item] += dic2[item]
            else:
                dic1[item] = dic2[item]
        for item in dic3.keys():
            if item in dic1:
                dic1[item] += dic3[item]
            else:
                dic1[item] = dic3[item]
        
        return [ str(dic1[item])+' '+item for item in dic1.keys()]

2.3.3 总结

.split()函数接收两个参数,第一个是分割符号,第二个是分割次数

第一个默认为空格,第二个分割次数默认为-1,也就是分割所有

但是在本题当中需要一次一次地分割,所以需要指定每次仅分割一次

如果分割后的字符串长度还是为1,那就证明没有分割,也就是不存在分隔符

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:50:47  更:2022-03-10 22:53:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:40:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码