算法练习Day5 (Leetcode/Python-哈希表)

哈希表在python中通常使用dictionary表示。以下是dict相关的一些常用指令

my_dict is a dictionary 

1. for key, value in my_dict.items(): 

2. my_dict.values(); my_dict.keys()

3. my_dict.get(num, 0)

Time complexity of the my_dict.get() method in Python dictionaries is typically O(1) on average.

Because dictionary lookups are implemented as hash table lookups, which are generally very efficient.

4. if num in my_dict. # check whether a key num is in dict table.  

set可以用于存储无序且唯一的元素。

在 Python 中,集合(Set)的实现主要有两种类型:基于哈希表的散列集合(set 类型)和基于有序列表的集合(collections.OrderedSet 或者使用 list 的方式)。

添加、删除、查找元素:

  • set 类型:平均时间复杂度 O(1)
  • collections.OrderedSet 类型:平均时间复杂度 O(n)(需要维护有序性)

并、交、差集:

  • set 类型:平均时间复杂度 O(len(s)),其中 s 是较小的集合
  • collections.OrderedSet 类型:平均时间复杂度 O(len(s) + len(t)),其中 s 和 t 是两个集合
# 使用哈希集合
hash_set = set()
hash_set.add(element)

# 使用有序集合
ordered_set = collections.OrderedSet()
ordered_set.add(element)

# 使用哈希集合
hash_set.remove(element)

# 使用有序集合
ordered_set.remove(element)

# 使用哈希集合
element in hash_set

# 使用有序集合
element in ordered_set

# 使用哈希集合
union_set = set1.union(set2)

# 使用有序集合
union_set = ordered_set1.union(ordered_set2)

# 使用哈希集合
intersection_set = set1.intersection(set2)

# 使用有序集合
intersection_set = ordered_set1.intersection(ordered_set2)

# 使用哈希集合
difference_set = set1.difference(set2)

# 使用有序集合
difference_set = ordered_set1.difference(ordered_set2)

242. Valid Anagram

Given two strings s and t, return true if t is an anagram of s, and false otherwise.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Example 1:

Input: s = "anagram", t = "nagaram"
Output: trues

思路: 

用dict来记录出现过的letter,dict的查询比数组更快。

Solution:

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if len(s) != len(t): # Early Stop
            return False
        
        freq = [0] * 26
        for i in range(len(s)): # two valid strings share same length, so one for-loop is enough! 
            freq[ord(s[i])-ord('a')] += 1 #get the ASCII of letter s[i]
            freq[ord(t[i])-ord('a')] -= 1

        '''
        # 以上也可替换为下面的这段
                
        freq = {} #[0] * 26
        for i in range(len(s)):
            freq[s[i]] = freq.get(s[i], 0) + 1
            freq[t[i]] = freq.get(t[i], 0) + 1
        '''
        
        for i in range(len(freq)):
            if freq[i] != 0:
                return False
        
        return True # Don't remember return True 

349. Intersection of Two Arrays

Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must be unique and you may return the result in any order.

Example 1:

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]

解法一:用dict存储已经出现的数字,搜索时if num in dict来判该数字是否在另一个数组中出现。

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)

解法一:”&“可以取两个set的交集。

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        return list(set(nums1) & set(nums2))

202. Happy Number

happy number is a number defined by the following process:

  • Starting with any positive integer, replace the number by the sum of the squares of its digits.
  • Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.
  • Those numbers for which this process ends in 1 are happy.

Return true if n is a happy number, and false if not.

Example 1:

Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

解法一:数组

class Solution(object):
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        record = set() 

        while n not in record:  
            record.add(n) # add n at first, instead at the end. 
            sum = 0 
            for i in str(n):
                sum += int(i)**2 # remember to initialize sum 
            if sum == 1:
                return True
            else:
                n = sum 
        return False

解法二:快慢指针

class Solution:
   def isHappy(self, n):      
       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):
       new_num = 0
       while n:
           n, r = divmod(n, 10)
           new_num += r ** 2
       return new_num

Tips: sum of the squares of its digits:

           n_str = str(n)
           for i in n_str:
               new_num+=int(i)**2
    # Extract digits using % and //
    while number > 0:
        digit = number % 10  # Get the last digit
        result += digit**2   # Add the square of the digit to the result
        number //= 10        # Remove the last digit
        while n:
            n, r = divmod(n, 10)
            new_num += r ** 2

1. Two Sum

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Solution1:字典法

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        record={}
        for i in range(len(nums)):
            if target - nums[i] in record: # 互补的值已经被记录在了dict中吗?如果是的话,直接report记录中这个值所对应的位置
                return [record[target - nums[i]],i] 
            record[nums[i]] = i # 值nums[i]所对应的位置i
        return [] #别忘了没找到配对的情况下return空

Solution2:排序后使用双指针法

注意!由于这里需要return的是原array里元素的序号,所以先用enumerate把原序号和元素的值记录下来[(0,2), (1,7), (2,11), (3,15)] 这样。然后再使用sorted(nums, key=lambda x: x[1]), 按照元素的值从小到大排序。最后return的时候由小到大输出排序后的原序号sorted([nums[l][0], nums[r][0]])。

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """        
        nums = list(enumerate(nums))
        print(nums)
        # Sort based on the values
        nums = sorted(nums, key=lambda x: x[1])
        print(nums)
        # Initialize two pointers
        l, r = 0, len(nums) - 1

        while l < r:
            current_sum = nums[l][1] + nums[r][1]

            if current_sum == target:
                # Return the sorted indices
                return sorted([nums[l][0], nums[r][0]])
            elif current_sum < target:
                l += 1
            else:
                r -= 1

        # If no solution is found
        return []
                

都是O(n)的时间复杂度

你可能感兴趣的:(哈希算法,算法)