(二刷)代码随想录算法训练营day6 | 242.有效的字母异位词,349. 两个数组的交集 ,202. 快乐数,1. 两数之和

哈希表理论基础:

  • 当需要快速判断一个元素是否出现在集合里的时候,则优先考虑哈希表。     

  • 出现哈希碰撞:

    • 拉链法:将发生碰撞的两个或多个元素存储在链表中

      • tip:拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。
    • 线性探测法:依靠哈希表中的空位来解决碰撞问题,出现碰撞则向下继续寻找可用空位。
      • tip:使用线性探测法,一定要保证tableSize大于dataSize
  • 常见哈希结构:list, set, dict (in python)

242.有效的字母异位词

  • 题解1:

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        
        temp = {}
        
        for char in s:
            if char not in temp:
                temp[char] = 1
            else:
                temp[char] += 1
                
        for char in t:
            if char in temp:
                temp[char] -= 1
            else:
                temp[char] = 1
                
        return True if all(value == 0 for value in temp.values()) else False
  • 题解2: (followup question)

    • The function ord() returns an integer representing the Unicode character.
    • for example, ord('a') = 97, ord('z') = 122, totally 26 characters or letters (a-z).
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        
        temp = [0] * 26
        
        for char in s:
            temp[ord(char) - ord('a')] += 1
            
        for char in t:
            temp[ord(char) - ord('a')] -= 1
            
        return all(x == 0 for x in temp)
            

383. 赎金信

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        temp = [0]*26
        for char in ransomNote:
            temp[ord(char) - ord('a')] += 1
        for char in magazine:
            temp[ord(char) - ord('a')] -= 1

        return all(x <= 0 for x in temp)

49. 字母异位词分组

Q: 如果只是判断 if temp not in res:,则会报错

A:How to Handle Unhashable Type List Exceptions in Python | Rollbar

  • The Python TypeError: unhashable type: 'list' usually means that a list is being used as a hash argument. This error occurs when trying to hash a list, which is an unhashable object. For example, using a list as a key in a Python dictionary will cause this error since dictionaries only accept hashable data types as a key. The standard way to solve this issue is to cast a list to a tuple, which is a hashable data type.
# python 2
class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        res = {}
        
        for word in strs:
            temp = [0] * 26
            for char in word:
                temp[ord(char) - ord('a')] += 1 #temp as key in res
              
            if tuple(temp) not in res:
                res[tuple(temp)] = [word]
            else:
                res[tuple(temp)].append(word)
                
        return res.values()
        #return list(res.values())

注意:

  • 上面代码为python2版本,最后返回的是res.values()也就是一个数组

  • 但是在python3下运行报错,原因是In Python 3, dict.values() (along with dict.keys() and dict.items()) returns a view, rather than a list. See the documentation here. You therefore need to wrap your call to dict.values() in a call to list.
  • 那么最后返回语句应该改为comment out的那一行

438.找到字符串中所有字母异位词

class Solution:
    def findAnagrams(self, s: str, p: str):
        ans = []

        for i in range(0, len(s)):
            if self.helper(s[i:len(p) + i], p) is True:
                ans.append(i)

        return ans

    def helper(self, s, t):
        temp = [0]*26
        for char in s:
            temp[ord(char) - ord('a')] += 1
        for char in t:
            temp[ord(char) - ord('a')] -= 1

        return all(x == 0 for x in temp)
class Solution:
    def findAnagrams(self, s: str, p: str):
        if len(p) > len(s):
            return []

        sCount = {}
        pCount = {}
        for i in range(len(p)):
            if p[i] not in pCount:
                pCount[p[i]] = 1
            else:
                pCount[p[i]] += 1

            if s[i] not in sCount:
                sCount[s[i]] = 1
            else:
                sCount[s[i]] += 1
            
        res = [0] if sCount == pCount else []
        left = 0
        for right in range(len(p), len(s)):
            if s[right] not in sCount:
                sCount[s[right]] = 1
            else:
                sCount[s[right]] += 1
            
            sCount[s[left]] -= 1
            if sCount[s[left]] == 0:
                sCount.pop(s[left])

            left += 1

            if sCount == pCount:
                res.append(left)
        
        return res

349. 两个数组的交集

  • 主要考察对于哈希表的运用,有如下两个题解:

class Solution(object):
    def intersection(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        return list(set(nums1) & set(nums2))
        
class Solution(object):
    def intersection(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        
        temp = {}
        for num in nums1:
            if num not in temp:
                temp[num] = 1
        print(temp)
        
        ans = []
        for num in nums2:
            if num in temp and num not in ans:
                ans.append(num)
                
        return ans

350. 两个数组的交集 II

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        res = []
        temp = {}
        for num in nums1:
            if num not in temp:
                temp[num] = 1
            else:
                temp[num] += 1

        for num in nums2:
            if num in temp and temp[num] > 0:
                res.append(num)
                temp[num] -= 1

        return res

202. 快乐数

  • trick:题目中说了会 无限循环,那么也就是说在求和的过程中,sum会重复出现。当需要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。

  • 利用哈希表,判断每次更新后的n,如果n在哈希表中出现过,则说明不是快乐数,因为会无限循环下去。接下来继续判断n是否等于1。

  • 在写helper 函数的时候不是很熟练,逻辑还是掌握的不熟。

二刷出错点:没有循环起来,没有加 whileTrue:

class Solution(object):
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        
        temp = {}
        while True:
            n = self.helper(n)
            if n == 1:
                return True
            
            if n not in temp:
                temp[n] = 1
            else:
                return False
            
        
    def helper(self, n):
        sum = 0
        while n > 0:
            sum += (n%10)**2
            n = n // 10
            
        return sum

1. 两数之和

  • 一切的起源(这是力扣的第一题, lol)

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashMap = {}

        for i in range(len(nums)):
            temp = target - nums[i]
            if temp not in hashMap:
                hashMap[nums[i]] = i
            else:
                return [i, hashMap[temp]]

总结:

  • 可以进一步整理出现哈希碰撞的两种解决方法,DataStructures_Python of Youtube) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值