力扣:1、两数之和
力扣小白的自闭学习过程,争取做到每日更新,加油
题目描述
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
一、暴力枚举
解题思路
- 枚举数组 n u m s nums nums中的每一位元素 x x x,寻找数组 n u m s nums nums中是否存在 t a r g e t − x target - x target−x;
- 值得注意的是,每一位 x x x之前的元素都与 x x x匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以只需要在 x x x后面的元素中寻找 t a r g e t − x target - x target−x;
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
n = len(nums)
for i in range(n):
for j in range(i+1, n):
if nums[i] == target - nums[j]:
return [i, j]
return []
复杂度
- 空间复杂度: O ( n 2 ) O(n^2) O(n2)
- 时间复杂度: O ( 1 ) O(1) O(1)
二、哈希表
原理
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)直接进行访问的数据结构。即,通过把关键码值
K
K
K映射到表中的一个位置
P
P
P来访问记录,以加快查找的速度。
P
=
f
(
K
)
P=f(K)
P=f(K)
其中,对应关系
f
f
f称为散列函数,又叫哈希(Hash函数),采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table)。
例:常见的除留余数法是最常见的构造散列函数的方法。对于哈希表长为m的散列函数公式为:
f
(
K
)
=
K
m
o
d
p
(
p
≤
m
)
f(K)=K\ mod\ p\ \ \ (p\le m)
f(K)=K mod p (p≤m)
其中,
m
o
d
mod
mod是取模(求余数)的意思。此外,不仅可以直接取模也可以经过其他函数运算后再进行取模。
若存在一个含有12个记录的关键字,现在针对它设计一个哈希表,并采用上方的运算公式。比如 12 m o d 11 = 1 12\ mod\ 11=1 12 mod 11=1,所以它存储在下标为5的位置。
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 0 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
关键字 | 12 | 24 | 36 | 48 | 60 | 72 | 84 | 96 | 108 | 120 | 132 | 144 |
使用除留余数法的一个经验是,若散列表表长为
m
m
m,通常
p
p
p为小于或等于表长(最好接近
m
m
m)的最小质数。
具体详细解释可参考:哈希表算法原理;除留余数法
解题思路
- 在遍历的同时,记录一些信息,以省去一层循环,是“空间换时间”的想法;
- 使用哈希表,不但可以快速从数组 n u m s nums nums中寻找是否存在目标元素 t a r g e t − x target - x target−x和目标元素的索引,而且可以将方法一中寻找数组 n u m s nums nums是否存在 t a r g e t − x target - x target−x的时间复杂度从 O ( n ) O(n) O(n)降低到 O ( 1 ) O(1) O(1);
- 需要注意的是,对于每一个 x x x,需要先查询哈希表中是否存在 t a r g e t − x target - x target−x,然后再将 x x x插入到哈希表中,即可确保不会让 x x x与自己匹配。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashtable = {}
for i, num in enumerate(nums):
another = target - num
if another in hashtable:
return [hashtable[another], i]
hashtable[num] = i
return []
复杂度
- 空间复杂度: O ( n ) O(n) O(n)
- 时间复杂度: O ( n ) O(n) O(n)
总结
哈希表是种数据结构,可以提供快速的插入操作和查找操作。缺点是它是基于数组的,数组创建后难于扩展,哈希表快被填满时存在不可避免的冲突现象,性能下降非常严重,即对不同的关键字可能得到同一哈希地址。
参考内容:
1、https://leetcode-cn.com/problems/two-sum/solution/python3-liang-shu-zhi-he-by-madmanlyy-41pi/
2、https://blog.csdn.net/weixin_39609527/article/details/111324242?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-0&spm=1001.2101.3001.4242
3、http://www.nowamagic.net/academy/detail/3008040