[英雄星球七月集训LeetCode解题日报] 第7日 哈希表
- 日报
- 题目
- 一、 970. 强整数
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 二、 914. 卡牌分组
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 三、 1497. 检查数组对是否可以被 k 整除
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 四、 面试题 17.05. 字母与数字
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
日报
题目
一、 970. 强整数
链接: 970. 强整数
1. 题目描述
2. 思路分析
- 分别枚举小于bound的x的次方结果、y的次方结果。
- 最终贡献答案的结果一定是两边的卷积组合。
- 不用担心复杂度,额外处理1,其余的数指数枚举会很快break。
3. 代码实现
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class Solution: def powerfulIntegers(self, x: int, y: int, bound: int) -> List[int]: h = set() g = set() if x == 1: h.add(1) else: for i in range(bound+1): if x**i > bound: break h.add(x**i) if y == 1: g.add(1) else: for i in range(bound+1): if y**i > bound: break g.add(y**i) ans = set() for i,j in product(h,g): if i +j <= bound: ans.add(i+j) return list(ans)
二、 914. 卡牌分组
链接: 914. 卡牌分组
1. 题目描述
2. 思路分析
- 题目要求每组都是x张相同牌。
- 显然k×x张相同牌可以分k组。
- 我们对每种牌计数,然后取所有数的最大公倍数x,就是能分的最少n/x组,每组x张。
- 计算到中途如果公倍数为1了就可以提前退出。
- 因此一个简单的优化:从小到大排序,公倍数更有可能提前降低。
3. 代码实现
复制代码
1
2
3
4
5
6
7
8
9
10
11class Solution: def hasGroupsSizeX(self, deck: List[int]) -> bool: cnt = Counter(deck) vs = sorted(list(cnt.values())) g = vs[0] for i in range(1,len(vs)): g = gcd(g,vs[i]) if g == 1: return False return g>1
三、 1497. 检查数组对是否可以被 k 整除
链接: 1497. 检查数组对是否可以被 k 整除
1. 题目描述
2. 思路分析
这题可以无脑的分类讨论:
- 首先每对里第一个数如果模k=a,则另一个数一定需要模k=k-a;
- 因此用m计数买个数字出现的次数,然后分配即可。
- 特别的:
- 如果模k0,则只能安排同样模k0的数字一组,因此这组判是否是偶数。
- 如果模k==i,则只能安排k-i,判断两种数是否一样多。
- 如果模k==自己,比如4模8还是4,只能安排同样的数字一组,因此判断是否是偶数。
- 那么我们计数完处理每种模的数字数量即可,复杂度O(n)+O(k)
3. 代码实现
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Solution: def canArrange(self, arr: List[int], k: int) -> bool: m = [0] * k for a in arr: m[a%k] += 1 if m[0] & 1: return False for i in range(1,k): if k - i == i: if m[i] & 1: return False else: if m[i] != m[k-i]: return False return True
四、 面试题 17.05. 字母与数字
链接: 面试题 17.05. 字母与数字
1. 题目描述
2. 思路分析
- 先预处理数组,字母记-1,数字记1,题目转化为求子段和为0的最长子段。
- 由于是连续的,我们先前缀和优化。
- 那么我们遍历前缀和数组时,对于每个presum[i],需要找一个前边的j,使presum[i]-presum[j]==0;
- 即presum[i]==presum[j]。那么用哈希表记录下每个值的第一次出现即可。
- 字段长度k=i-j,对应的更新k和答案的左端点j。最后输出原数组对应位置子段即可。
- 特殊的,0第一次出现位置应该是-1。
3. 代码实现
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Solution: def findLongestSubarray(self, array: List[str]) -> List[str]: if len(array) <= 1: return [] t = [1 if a.isdigit() else -1 for a in array] # 预处理t,题目转化为求t中和为0的最长子段。 # print(t) presum = list(accumulate(t)) # print(presum) d = {0:-1} k = 0 ans = 0 for i,s in enumerate(presum): if s in d: pre = d[s] if i - pre > k: k = i - pre ans = pre else: d[s] = i # print(ans,k) return array[ans+1:ans+1+k] if k else []
最后
以上就是繁荣大碗最近收集整理的关于[英雄星球七月集训LeetCode解题日报] 第7日 哈希表的全部内容,更多相关[英雄星球七月集训LeetCode解题日报]内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复