1. 两数之和 (Python3)

本文介绍了如何使用哈希表(Python字典)解决LeetCode的两数之和问题,通过枚举一个数并将其作为常量处理,转换为查找其补数的问题。重点讲解了正确使用哈希表存储元素及其索引的重要性,以及处理重复元素和效率分析。
摘要由CSDN通过智能技术生成

Problem: 1. 两数之和

思路

参考:

  • https://leetcode.cn/problems/two-sum/solutions/2326193/dong-hua-cong-liang-shu-zhi-he-zhong-wo-0yvmj

  • https://leetcode.cn/problems/two-sum/solution/dong-hua-cong-liang-shu-zhi-he-zhong-wo-0yvmj/

  • 灵神:“很多涉及到「两个变量」的题目,都可以枚举其中一个变量,把它当成常量看待,从而转换成「一个变量」的问题。代码实现时,通常来说「枚举右,寻找左」是更加好写的。”

解题方法

  1. nums[i] + nums[j] = target可转变为nums[j]=target-nums[i],非常适合使用哈希表;

  2. 使用字典构建哈希表,python中字典存贮 key-value pair,符合 hash map;

  3. python中的 enumerate() 方法实现element和index的枚举;

  4. 理解 hash map 的构建,核心语句在于 hashtab[x] = i,参考 ChatGPT:To create a hash table for the twoSum problem, you should map each number to its index. This is done in a loop, where you iterate over the numbers in the list and update the hash table (dictionary) with the number as the key and its index as the value;

  5. 构建 hash map 后,向左侧进行比较,这也是为什么 return [hash[target - x], i]

一些额外的讨论, 均来自于 ChatGPT

1 关于 hashtab[x] = i 有些反直觉的讨论:

Using hashtab[i] = x instead of hashtab[x] = i in the context of the “Two Sum” problem changes the meaning and functionality of the hash table in a way that would not solve the problem as intended. Let’s examine why:

  1. Original Purpose (hashtab[x] = i):
  • In the original code, hashtab[x] = i stores each number x from the nums list as a key, with its index i as the value.

  • The purpose is to quickly check if the complement of a number (i.e., target - x) exists in nums. If it does, the indices of these two numbers are returned.

  1. If Changed to hashtab[i] = x:
  • Using hashtab[i] = x would store the index i as the key and the number x as the value.

  • This reversal makes it difficult to find the complement of a number efficiently. You would know the indices (keys) and could look up the numbers (values), but the problem requires the opposite: given a number, you need to find its index.

  • In the “Two Sum” problem, you are not looking for a specific index; you are looking for a number that, when added to the current number, equals the target. The indices are not relevant until you find such a pair of numbers.

  1. Efficiency and Purpose:
  • The hash table is used for efficiently finding whether the complement of the current number exists in the array. By storing numbers as keys, you can quickly check the presence of the complement using a key lookup (if target - x in hash).

  • If you store indices as keys, you would have to iterate over the hash table to find the required number, which defeats the purpose of using a hash table for efficient lookup.

In summary, hashtab[x] = i is the correct approach for the “Two Sum” problem because it allows for the efficient lookup of numbers and their indices, which is the core requirement for solving this problem. Storing indices as keys (hashtab[i] = x) would not serve the intended purpose of the hash table in this specific context.

2 关于input有相同元素,hash table如何处理:

The input can have two same numbers, like nums = [1, 1, 2, 3], and the hash table approach will still work for the “Two Sum” problem, but with a caveat.

When you use hashtab[x] = i to store each number x from the nums list and its index i in the hash table, if the same number appears more than once in the list, the hash table will only retain the index of the last occurrence of that number. This is because each key in a Python dictionary must be unique, and adding an entry with an existing key will overwrite the previous value.

In the context of the “Two Sum” problem, this behavior is generally acceptable and can still lead to a correct solution. Consider your example nums = [1, 1, 2, 3]. If the target is 2, the algorithm will look for pairs that add up to 2. When it encounters the first 1, it doesn’t find its complement (1) in the hash table, so it continues. When it encounters the second 1, the first 1 is already in the hash table (although overwritten by the second 1, but they are the same value with different indices), and the algorithm correctly identifies the pair (1, 1).

However, you should be aware of this behavior as it could impact the logic in scenarios where knowing all occurrences of a number might be important. In the standard “Two Sum” problem, where you are just looking for any pair that adds up to the target, this approach is sufficient.

3 关于对python中字典的认识

In Python, when you use a dictionary (dict), you typically check for the existence of keys rather than values. The syntax if key in dict checks if a particular key is present in the dictionary. However, it’s also possible to check for the existence of a value in a dictionary, but the method is slightly different and less efficient. Let me explain both:

  1. Checking for Key Existence:
  • To check if a key exists in a dictionary, you use if key in dict. This is a fast operation because dictionaries in Python are implemented as hash tables, which allow for very quick key lookups.

  • In the context of your question, if target - x in hash is checking if the key target - x exists in the hash dictionary.

  1. Checking for Value Existence:
  • To check if a value exists in a dictionary, you can use if value in dict.values(). This will check if the specified value is one of the dictionary’s values.

  • However, this is a slower operation compared to checking for a key. The reason is that dict.values() returns a view of all the values in the dictionary, and Python has to iterate over these values to check for the existence of the specified value.

In summary, while you can check for the existence of both keys and values in a dictionary, checking for keys is a much more efficient operation in Python. In most algorithmic problems, including the “Two Sum” problem, you usually check for the existence of keys for this reason.

4 python中字典是基于 hash table 实现的

In Python, a dictionary (dict) is indeed implemented as a hash table. This implementation choice has important implications for the time complexity of various operations performed with dictionaries. Let’s explore this in more detail:

  1. Dictionary Creation: Creating a dictionary (e.g., my_dict = {} or my_dict = dict()) is an O(1) operation. However, populating a dictionary with N elements (key-value pairs) will have a time complexity of O(N), as each insertion is an O(1) operation on average.

  2. Insertion: Inserting a new key-value pair into a dictionary (my_dict[key] = value) is typically an O(1) operation. This efficiency is due to the underlying hash table, which allows for quick computation of the index where the value should be stored based on the hash of the key.

  3. Lookup: Looking up a value by its key (my_dict[key]) is also an O(1) operation on average, for the same reasons as insertion. The hash of the key is computed, leading directly to the index where the value is stored.

  4. Deletion: Deleting a key-value pair from the dictionary (del my_dict[key]) is similarly an O(1) operation. It involves computing the hash of the key to find the index and then removing the entry at that index.

  5. Collision Handling: Hash collisions (where different keys have the same hash) are handled internally, but the way Python does it helps maintain the average O(1) time complexity for insertion, lookup, and deletion. Python uses a method called “open addressing” to resolve collisions, which involves searching for the next available slot in the event of a collision.

  6. Iteration: Iterating over the keys or values of a dictionary (for example, using for key in my_dict) has a time complexity of O(N), as it goes through every entry in the dictionary.

  7. Dynamic Resizing: Python dictionaries are dynamically resized when they get too full. This resizing operation can temporarily cause a larger time complexity for the insertion that triggers the resize. However, because the resizes happen exponentially less frequently as the dictionary grows, the average time complexity of insertions remains O(1).

In conclusion, the Python dictionary is a highly efficient data structure for many common operations due to its hash table implementation. This efficiency is particularly evident in scenarios involving frequent insertions, lookups, and deletions, where the average time complexity remains O(1).

复杂度

时间复杂度:

O ( n ) O(n) O(n)

空间复杂度:

O ( n ) O(n) O(n)

Code

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        
        # 创建一个字典作为 hash tabel 散列表
        # 理清思路,这个字典里的key-value pair为:key对应nums中的value,value对应nums中的value的index
        hashtab = {}

        for i, x in enumerate(nums): # 通过 enumerate 创建 索引
            y = target - x 
            if y in hashtab: # 检查字典中的元素,通常都是 if key in dict,即检测key是否在!
                return [hashtab[y], i] # 通常来说「枚举右,寻找左」是更加好写的 —— 灵神

            hashtab[x] = i # 将元素存入散列表,注意,以x为key,i为value!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值