[英雄星球六月集训LeetCode解题日报] 第七日 哈希表

这篇博客介绍了使用哈希表解决LeetCode上的几道题目,包括数组中重复的数据、检查字符串几乎相等、判断数字计数与数位值的关系、寻找两句话中的不常见单词以及爱吃香蕉的珂珂问题。通过原地哈希、计数比较等方法,实现了高效的空间复杂度解决方案。
摘要由CSDN通过智能技术生成

一、 442. 数组中重复的数据

链接: 442. 数组中重复的数据

1. 题目描述

给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。

你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。

2. 思路分析

其实哈希计数很简单,但是题目要求空间复杂度O(1)。
因此可以原地哈希,把每个数放到对应的位置:
每次操作把本位置的数换出去,如果换进来的数不对,继续换出去。
这样每次都能至少让一个数在正确位置。

3. 代码实现

class Solution:
    def findDuplicates(self, nums: List[int]) -> List[int]:
        n = len(nums)
        for i in range(n):         
            while nums[i]  != nums[nums[i] - 1] :
                nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
        return [nums[i] for i in range(n) if nums[i]-1 != i]

二、 2068. 检查两个字符串是否几乎相等

链接: 2068. 检查两个字符串是否几乎相等

1. 题目描述

如果两个字符串 word1 和 word2 中从 ‘a’ 到 ‘z’ 每一个字母出现频率之差都 不超过 3 ,那么我们称这两个字符串 word1 和 word2 几乎相等 。

给你两个长度都为 n 的字符串 word1 和 word2 ,如果 word1 和 word2 几乎相等 ,请你返回 true ,否则返回 false 。

一个字母 x 的出现 频率 指的是它在字符串中出现的次数。

2. 思路分析

计数比较就行。

3. 代码实现

class Solution:
    def checkAlmostEquivalent(self, word1: str, word2: str) -> bool:
        c1,c2 = Counter(word1),Counter(word2)
        for c,v in c1.items():
            if abs(v-c2.get(c,0)) >3:
                return False
        for c,v in c2.items():
            if abs(v-c1.get(c,0)) >3:
                return False
        return True

三、 2283. 判断一个数的数字计数是否等于数位的值

链接: 2283. 判断一个数的数字计数是否等于数位的值

1. 题目描述

给你一个下标从 0 开始长度为 n 的字符串 num ,它只包含数字。

如果对于 每个 0 <= i < n 的下标 i ,都满足数位 i 在 num 中出现了 num[i]次,那么请你返回 true ,否则返回 false 。

2. 思路分析

这题主要是类型转换要注意。

3. 代码实现

class Solution:
    def digitCount(self, num: str) -> bool:
        cnt = Counter(num)
        # 注意类型转换
        return all(int(num[i]) == cnt.get(str(i), 0) for i in range(len(num)))

四、884. 两句话中的不常见单词

链接: 884. 两句话中的不常见单词

1. 题目描述

句子 是一串由空格分隔的单词。每个 单词 仅由小写字母组成。

如果某个单词在其中一个句子中恰好出现一次,在另一个句子中却 没有出现 ,那么这个单词就是 不常见的 。

给你两个 句子 s1 和 s2 ,返回所有 不常用单词 的列表。返回列表中单词可以按 任意顺序 组织。

2. 思路分析

直接在两个一起计数,找频次1的。

3. 代码实现

class Solution:
    def uncommonFromSentences(self, s1: str, s2: str) -> List[str]:
        return [x for x,v in Counter(s1.split(' ') + s2.split(' ')).items() if v == 1]

五、附每日一题 875. 爱吃香蕉的珂珂

链接: 875. 爱吃香蕉的珂珂

1. 题目描述

珂珂喜欢吃香蕉。这里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 h 小时后回来。

珂珂可以决定她吃香蕉的速度 k (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 k 根。如果这堆香蕉少于 k 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。

珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。

返回她可以在 h 小时内吃掉所有香蕉的最小速度 k(k 为整数)。

2. 思路分析

速度快了就会时间短,速度慢了就时间长,要求时间不能超过h。因此可以二分。
二分上下界:[1,max(piles)]。
python的bisect参数要好好理解。
只能升序搜,key参数是指原数组每个数经过key计算后,第一个不大于 指定数据(-h)的数。
这里因为k和计算式的结果大小是相反的,所以加负号。
返回值是下标,因此range从0开始,这样可以让下标=值,但搜索下限指定为1。
在这里插入图片描述

3. 代码实现

# class Solution:
#     def minEatingSpeed(self, piles: List[int], h: int) -> int:
#         a = range(1,+1)
#         ans = max(piles)+1
#         l,r = 1, ans
#         m = (l+r) // 2
#         while l<r:
#             m = (l+r) // 2
#             s = sum([ceil(x/m) for x in piles])
#             # print(l,r,m,s,h)
#             # if s == h:
#             #     return m
#             if s > h:
#                 l = m+1
#             elif s <= h:
#                 ans = min(ans,m)
#                 r = m 

#         return ans

class Solution:
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
        return bisect_left(range(0,max(piles)+1), -h, lo=1, key=lambda k: -sum([ceil(x/k) for x in piles]))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值