哈希表理论
- 数组就是一个哈希表
- 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
- 哈希法牺牲了空间换取了时间。
leetcode 242
leetcode题目链接
代码随想录文章讲解
代码随想录视频讲解
有效的字母异位词
方法一:哈希法
重点
- 对于
s
,+=;对于t
,-= - 最后使用遍历
record
数组的方法比较节省时间,这样如果出现第一个不为0的元素就知道一定有字符不同
完整python版答案
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
其他方法
完整python版答案
defaultdict
的思路
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
from collections import defaultdict
s_dict = defaultdict(int)
t_dict = defaultdict(int)
for x in s:
s_dict[x] += 1
for x in t:
t_dict[x] += 1
return s_dict == t_dict
Counter
的思路
class Solution(object):
def isAnagram(self, s: str, t: str) -> bool:
from collections import Counter
a_count = Counter(s)
b_count = Counter(t)
return a_count == b_count
leetcode 349
leetcode题目链接
代码随想录文章讲解
代码随想录视频讲解
两个数组的交集
方法0:使用集合
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
set1 = set()
res = set()
for i in nums1:
set1.add(i)
for i in nums2:
if i in set1:
res.add(i)
return list(res)
方法一:使用字典和集合
重点
注意:del table[num]
这行是很有必要的。因为它在找到交集的元素后从字典中删除了它们,从而可能减少了后续的查找时间。当然不加这一行也可以完成任务。
完整python版答案
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 使用哈希表存储一个数组中的所有元素
table = {}
for num in nums1:
table[num] = table.get(num, 0) + 1
# 使用集合存储结果
res = set()
for num in nums2:
if num in table:
res.add(num)
del table[num]
return list(res)
方法二:使用数组
重点
同上一题
leetcode做了长度限制之后用数组更快
完整python版答案
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
方法三:使用集合
重点
完整python版答案
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(nums2))
leetcode 202
快乐数
方法一:使用集合
完整python版答案
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
方法二:使用集合
完整python版答案
class Solution:
def isHappy(self, n: int) -> bool:
record = set()
while n not in record:
record.add(n)
new_num = 0
n_str = str(n)
for i in n_str:
new_num+=int(i)**2
if new_num==1: return True
else: n = new_num
return False
方法三:使用数组
完整python版答案
class Solution:
def isHappy(self, n: int) -> bool:
record = []
while n not in record:
record.append(n)
new_num = 0
n_str = str(n)
for i in n_str:
new_num+=int(i)**2
if new_num==1: return True
else: n = new_num
return False
方法四:使用快慢指针
完整python版答案
class Solution:
def isHappy(self, n: int) -> bool:
slow = n
fast = n
while self.get_sum(fast) != 1 and self.get_sum(self.get_sum(fast)):
slow = self.get_sum(slow)
fast = self.get_sum(self.get_sum(fast))
if slow == fast:
return False
return True
def get_sum(self,n: int) -> int:
new_num = 0
while n:
n, r = divmod(n, 10)
new_num += r ** 2
return new_num
方法五:使用集合+精简
完整python版答案
class Solution:
def isHappy(self, n: int) -> bool:
seen = set()
while n != 1:
n = sum(int(i) ** 2 for i in str(n))
if n in seen:
return False
seen.add(n)
return True
方法六:使用数组+精简
完整python版答案
class Solution:
def isHappy(self, n: int) -> bool:
seen = []
while n != 1:
n = sum(int(i) ** 2 for i in str(n))
if n in seen:
return False
seen.append(n)
return True
leetcode 1
leetcode题目链接
代码随想录文章讲解
代码随想录视频讲解
两数之和
方法0:
重点
注意谁是key
谁是value
完整python版答案
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
dict = {}
res = []
for i in range(len(nums)):
another = target - nums[i]
if another in dict:
res = [dict[another],i]
return res
dict[nums[i]] = i
方法一:使用字典
重点·=
使用enumerate
函数可以使代码更为Pythonic
完整python版答案
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: # 遍历当前元素,并在map中寻找是否有匹配的key
return [records[target- value], index]
records[value] = index # 如果没找到匹配对,就把访问过的元素和下标加入到map中
return []
方法二:使用集合
重点
nums.index(complement)
方法
完整python版答案
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
#创建一个集合来存储我们目前看到的数字
seen = set()
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [nums.index(complement), i]
seen.add(num)
方法三:使用双指针
完整python版答案
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
# 对输入列表进行排序
nums_sorted = sorted(nums)
# 使用双指针
left = 0
right = len(nums_sorted) - 1
while left < right:
current_sum = nums_sorted[left] + nums_sorted[right]
if current_sum == target:
# 如果和等于目标数,则返回两个数的下标
left_index = nums.index(nums_sorted[left])
right_index = nums.index(nums_sorted[right])
if left_index == right_index:
right_index = nums[left_index+1:].index(nums_sorted[right]) + left_index + 1
return [left_index, right_index]
elif current_sum < target:
# 如果总和小于目标,则将左侧指针向右移动
left += 1
else:
# 如果总和大于目标值,则将右指针向左移动
right -= 1
方法四:暴力法
完整python版答案
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
return [i,j]