#242 有效的字母异位词
242. 有效的字母异位词 - 力扣(LeetCode)https://leetcode.cn/problems/valid-anagram/
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
record = [0] * 26
for i in s:
#并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
record[ord(i) - ord("a")] += 1
for i in t:
record[ord(i) - ord("a")] -= 1
for i in range(26):
if record[i] != 0:
#record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
return False
return True
record[ord(i) - ord("a")] += 1
是在更新一个用于记录字符出现频率的数组。让我们详细解释这行代码:
-
ord(i)
:这是 Python 的ord
函数,它返回字符i
的 ASCII 数值。例如,ord("a")
返回 97。 -
ord("a")
:同样,ord("a")
返回 97,这是小写字母a
的 ASCII 数值。 -
ord(i) - ord("a")
:通过减去ord("a")
,我们将字符i
的 ASCII 数值转换成一个相对于a
的索引。例如,对于i = "c"
,ord("c") - ord("a")
计算结果为 2。这使得a
到z
映射到 0 到 25 的范围内。
#349. 两个数组的交集
349. 两个数组的交集 - 力扣(LeetCode)https://leetcode.cn/problems/intersection-of-two-arrays/description/
这道题目,主要要学会使用一种哈希数据结构:unordered_set,这个数据结构可以解决很多类似的问题。
注意题目特意说明:输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序
这道题用暴力的解法时间复杂度是O(n^2),那来看看使用哈希法进一步优化。
那么用数组来做哈希表也是不错的选择,例如242. 有效的字母异位词(opens new window)
但是要注意,使用数组来做哈希的题目,是因为题目都限制了数值的大小。
而这道题目没有限制数值的大小,就无法使用数组来做哈希表了。
而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
此时就要使用另一种结构体了,set ,关于set,C++ 给提供了如下三种可用的数据结构:
- std::set
- std::multiset
- std::unordered_set
std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
count1 = [0]*1001
count2 = [0]*1001
result = []
for i in range(len(nums1)):
count1[nums1[i]]+=1
for j in range(len(nums2)):
count2[nums2[j]]+=1
for k in range(1001):
if count1[k]*count2[k]>0:
result.append(k)
return result
使用集合 set比较简单。
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(nums2))
#第202题. 快乐数
202. 快乐数 - 力扣(LeetCode)https://leetcode.cn/problems/happy-number/description/
class Solution:
def isHappy(self, n: int) -> bool:
record = set()
while True:
n = self.get_sum(n)
if n == 1:
return True
if n in record:
return False
else:
record.add(n)
def get_sum(self,n:int) -> int:
new_num = 0
while n:
n,r = divmod(n,10)
new_num += r**2
return new_num
#1.两数之和
1. 两数之和 - 力扣(LeetCode)https://leetcode.cn/problems/two-sum/description/
这道题目中并不需要key有序,选择std::unordered_map 效率更高! 使用其他语言的录友注意了解一下自己所用语言的数据结构就行。
接下来需要明确两点:
- map用来做什么
- map中key和value分别表示什么
map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)
接下来是map中key和value分别表示什么。
这道题 我们需要 给出一个元素,判断这个元素是否出现过,如果出现过,返回这个元素的下标。
那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。
所以 map中的存储结构为 {key:数据元素,value:数组元素对应的下标}。
在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
records = dict()
for index, value in enumerate(nums):
if target-value in records:
return [records[target-value],index]
records[value] = index
return []
不要忘了,if 不在records中,要存进records 字典中。
最后return空,在for下面而不是if下面。