1.基础语法
1)-> List[int]
-> List[int] 表示该函数应返回一个整数列表
nums: List[int], target: int表示应该nums是整数列表,并且应该target是整数。
2)哈希表
有没有想过,Python中的字典为什么这么高效稳定。原因是他是建立在hash表上。了解Python中的hash表有助于更好的理解Python,因为Python中字典无处不在。
哈希函数是一个可以将任意长度的数据块映射到固定长度的值,这个步骤称为hash,也就是散列。
hash 函数有三个主要的特征:
计算迅速:计算一个数据块的hash值非常快
确定性:相同用字符串会产生相同的hash值
结果固定长度:不管输入的是,一个字节还是十个字节,或者上万个字节,结果总是预先确定的长度。
另一个特征在hash函数中非常普遍,即他们是单方向的:通过函数实现后,原始数据丢失了,我们可以通过字符串得到一个hash值,但不能通过一个hash也就是散列得到原始的字符串(因为有对数据降维的方法会造成数据的丢失)。这种特性并不是对所有hash函数的强制性规定,但是当需要加密安全时,这种性质还是挺好用的。
一些比较受欢迎的算法包括:MD5、SHA-1、SHA-2,NTLM.
>>> hash(1)
1
>>> hash(10)
10
>>> hash(10.00)
10
>>> hash(10.01)
230584300921368586
>>> hash(-10.01)
-230584300921368586
如果你好奇为什么这些hash值看起来有不同的长度,请记住在Python中hash()函数返回的是整数对象,他们都会在标准的64位Python解释器中通过24字节呈现。
正如你可以看到的,整数的哈希值默认的就是它本身,不管你哈希的数据类型是什么,所以整数1和浮点数1.0哈希值都是1.
这个有什么特殊的么,这个展示了你之前学到的知识,也就是hash函数经常是单向的函数,如果两个不同的对象具有相同的hash值,根本不可能做反向工程,也就是从hash值返回到原始的对象,这也就使得被hash的原始数据类型的信息被丢失。
另几个有趣的可以关注的hash事情是,小数的散列值不同于它本身,负数具有负的哈希值。还有一点,就是如果两个对象具有相同的哈希值,称为哈希碰撞。
哈希一个字符串不同于对数值进行哈希。
>>> hash("Bad Behaviour")
7164800052134507161
哈希表就结合了数组和链表的优点,左边是一个数组,右边是链表,数组会指向一个链表,链表上存着很多的key-value的数据结构
Hash表插入演示,这里最重要就是hash函数,哈希函数能快速将一个数值转换成哈希值(整数)。所以哈希表必须保持哈希值的计算一致,如果两个哈希值是不相同的,那么这两个哈希值的原始输入也是不相同的。那如果两个不同的输入得到相同的哈希值=哈希值冲突;
我们输入关键字x,使用哈希函数f(x)计算出哈希值y,然后使用哈希值y来找特定的数组下标,并在对应位置插入新数据。如果计算得到的哈希值超过了数组的索引范围,则可以将计算出来的值对数组长度取余,之后将key-value插入到对应的链表中,因此他们的时间复杂度为O(1),如果存在碰撞,则时间复杂度为O(k)
Python字典的底层实现是哈希表。什么是哈希表,简单来说就是一张带索引和存储空间的表,对于任意可哈希对象,通过哈希索引的计算公式:hash(hashable)%k(对可哈希对象进行哈希计算,然后对结果进行取余运算),可将该对象映射为0到k-1之间的某个表索引,然后在该索引所对应的空间进行变量的存储/读取等操。
#利用hash表来实现
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashtable = dict()
for i, num in enumerate(nums):
if target - num in hashtable:
return [hashtable[target - num], i]
hashtable[nums[i]] = i
return []
3)数组
(1)数组内字符串转int
xxx = ['1','2']
xxx = list(map(int,xxx))
arr = ['22','44','66','88']
arr = list(map(int,arr))
print(arr)
#[22, 44, 66, 88]
(2)数组矩阵运算
如果不使用第三方库的时候只能遍历来实现数组对应元素的加减法
c = [vertex[i] + act_vertex[i] for i in range(len(vertex))]