二刷复习
文章目录
- 二刷复习
- 哈希表和哈希法
- unordered 和 ordered 的不同
- 242.有效字母的异位词
- 349.两个数组的交集
- 202.快乐数
- 两数之和
- 四数相加2
- 383.赎金信
- 三数之和(这道题需要重复做, 双指针)
- 四数之和
哈希表和哈希法
哈希表:这是两种不一样的东西,首先哈希表是一种底层的数据结构
 散列:其次,哈希法也叫散列法,是一种映射,key value的映射
python中如果想使用散列法可以使用set或者dict, set只储存键不储存值,dict可以储存键值对。
 两者的底层实现都是哈希表,应该是相当于unordered_set和unordered_map; 所以dict可以在常数级别的增 删 查
哈希法,当我们遇到了要快速判断一个元素是否出现集合里的时候 或者 需要判断一个元素是否出现过,就要考虑哈希法。
unordered 和 ordered 的不同
首先无序和有序是针对key值的
(无序)unordered_set, map 底层是哈希表 所以查询 增删效率都是O(1)
(有序)ordered_set的话, c++std库中分为std::set和std::multiset; 我们知道set储存key值,ordered_set底层是用红黑树去储存key值的,这是一种平衡二叉树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。
 set只能增删
 
 ordered_map, map中key不能修改,value可以修改, 有序map的话 key是用红黑树储存的
 
242.有效字母的异位词
有效字母异位词
 from collections import Counter
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        a, b = Counter(s), Counter(t)
        return a == b
349.两个数组的交集
两个数组的交集
 交集用 & , 并起来用 |
class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        return list(set(nums1) & set(nums2))
202.快乐数
快乐数
为什么这道题在哈希表这节里,因为在这个循环中可能有一个数反复出现,颠来倒去还是那个就会死循环; 这个时候就可以考虑用哈希了,每次我们把结果加进集合里,如果发现出现在集合里了我们return False; 出现1了我们return True
数位运算
while n:
    x = n % 10
    对x操作
    n = n // 10
def isHappy(self, n: int) -> bool:
        def cal(num: int) -> int:
            sum_ = 0
            while num:
                sum_ += (num % 10) ** 2
                num = num // 10
            return sum_
 
        record = set()
        while True:
            sum = cal(n)
            if sum == 1: return True
            if sum in record: return False
            else: record.add(sum)
            n = sum
两数之和
两数之和
 哈希表储存的是 数组下标, 由于我们遍历的时候可以知道其中一个下标了,可以直接return [i, a[tar-nums[i]]]
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        a = dict()
        for i in range(len(nums)):
            if target-nums[i] in a: return [i, a[target-nums[i]]]
            else: a[nums[i]] = i
四数相加2
四数相加2
 这道题的关键在于,四个数组是分离的,可以单独从中选的,你选12 一组 34一组 和 13一组24一组是等价的;思路就在于分组做哈希
class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hashtable = dict()
        for a in nums1:
            for b in nums2:
                if a+b not in hashtable: hashtable[a+b] = 1
                else: hashtable[a+b] += 1
        cnt = 0
        for c in nums3:
            for d in nums4:
                if -(c+d) in hashtable: cnt += hashtable[-c-d]
        return cnt
383.赎金信
383赎金信
 思路: 就是看第二个字符串是否能完全提供给第一个字符串,首先是第一个字符串有的元素第二个字符串都得有,其次对应的value要足够
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        r, m = Counter(ransomNote), Counter(magazine)
        for key in r.keys():
            if key not in m.keys(): return False
            else:
                if r[key] <= m[key]: continue
                else: return False
        return True
三数之和(这道题需要重复做, 双指针)
三数之和
 一个是双指针逻辑,一个是去重逻辑;去重放在哪;先放进去一组之后再去重;
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        if n < 3: return []
        res = []
        nums.sort()
        for i in range(n):
            if nums[i] > 0: break
            if i > 0 and nums[i] == nums[i-1]: continue
            l, r = i+1, n-1
            while l < r:
                if nums[i] + nums[l] + nums[r] == 0: 
                    res.append([nums[i], nums[l], nums[r]])
                    while l < r and nums[l] == nums[l+1]: l += 1
                    while l < r and nums[r] == nums[r-1]: r -= 1
                    l += 1
                    r -= 1
                elif nums[i] + nums[l] + nums[r] < 0: l += 1
                else: r -= 1
        return res
四数之和
四数之和
 和上面三数之和逻辑一样,都是双指针放缩;只是在双指针前增加了一层
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        n = len(nums)
        if n < 4: return []
        res = []
        nums.sort()
        for i in range(n):
            if i > 0 and nums[i] == nums[i-1]: continue
            for j in range(i+1,n):
                if j > i+1 and nums[j] == nums[j-1]: continue
                p = j + 1
                q = n-1
                while p < q:
                    if nums[i] + nums[j] + nums[p] + nums[q] > target: q -= 1
                    elif nums[i] + nums[j] + nums[p] + nums[q] < target: p += 1
                    else:
                        res.append([nums[i], nums[j], nums[p], nums[q]])
                        while p < q and nums[p] == nums[p + 1]: p += 1
                        while p < q and nums[q] == nums[q - 1]: q -= 1
                        p += 1
                        q -= 1
        return res 


















