记录每天刷题学到的东西
刷题网站Leetcode,也不知道从什么题目开始刷,也忘了语法的基础知识,也不太得记得常用的数据结构,但是想要斩获大厂的实习offer!
Leetcode开头解释
首先需要熟悉一下python3开头的各部分是啥意思:
class Solution:
def isOneBitCharacter(self, bits: List[int]) -> bool:
Solution 是一个类,类中的函数用def定义,面向对象编程即每一个对象都可以通过函数的接口来赋予属性或者进行数据操作,这个接口就叫做self(为假设的用户进行属性和数据操作,使得真用户进来之后能够直接享受这些操作) [^2]
[^2] https://blog.youkuaiyun.com/xrinosvip/article/details/89647884
List相关的函数
1.获取List的长度:
len(list_name)
2.列表最后一个元素
list_name[-1],列表倒数第二个元素:list_name[-2]
3.列表中的元素为列表(矩阵)的表示:
X=array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]])
X[:,0]就是取矩阵X的所有行的第0列的元素,X[:,1] 就是取所有行的第1列的元素。
X[:, m:n]即取矩阵X的所有行中的的第m到n-1列数据,含左不含右。
X[0,:]就是取矩阵X的第0行的所有元素,X[1,:]取矩阵X的第一行的所有元素。
参考:
https://www.cnblogs.com/abella/p/10207945.html
4.向列表中插入元素
(1).在列表末尾追加append()
list_name.append("apple")
(2).在指定位置追加元素insert()
list_name.insert(location,"apple")
创建一个任意长度连续数字的数组:
a = list(range(1,101)) #生成一个1到100的数组
字典
- 避免洪水泛滥
字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值key->value对用冒号:分割,每个对之间用逗号(,)分割,整个字典包括在花括号{}中,格式如下所示:
d={key1 : value1, key2: value2, key3: value3}
键必须是唯一的,但值则不必,值可以去任何数据类型:
dict = {‘name’: ‘runoob’, ‘likes’: 123, ‘url’: ‘www.runoob.com’}
访问字典里面的值:
dict = {‘Name’: ‘Runoob’, ‘Age’: 7, ‘Class’: ‘First’}
dict[‘Name’] 就可以访问对应的值Runoob
删除字典里面的值:
del dict[‘Name’] #删除键’Name’
dict.clear() #清空字典
del dict #删除字典
计算字典元素的个数,即键的总数: len(dict)
lakeToDays = collections.defaultdict(collections.deque)
collections.defaultdict([default_factory[, …]])
Python中通过Key访问字典,当Key不存在时,会引发‘KeyError’异常。为了避免这种情况的发生,可以使用collections类中的defaultdict()方法来为字典提供默认值。该函数返回一个类似字典的对象。defaultdict是Python内建字典类(dict)的一个子类,它重写了方法_missing_(key), 增加了一个可写的实例变量 default_factory,default_factory被missing()方法使用,如果该变量存在,则用以初始化构造器,如果没有,则为None。其它的功能和dict一样。
from collections import defaultdict
s = [('yellow',1),('blue',2),('yellow',3),('blue',4),('red',1)]
d = defaultdict(list)
for k, v in s:
d[k].append(v)
a = sorted(d.items())
print(a)
defaultdict还可以用来计数,将default_factory设为int即可
from collections import defaultdict
s='mississippi'
d = defaultdict(int)
for K in s:
d[K]= d[K]+ 1
print('\n', d)
a = sorted(d.items())
print('\n', a)
collections是python内建的一个集合模块,里面封装了许多集合类,其中队列相关的集合只有一个: deque, deque是双边队列(double-ended queue),具有队列和栈的性质,在list的基础上增加了移动,旋转和增删等:
d=collections.deque([]) #建立双边队列
d.append('a') # 在最右边添加一个元素,此时 d=deque('a')
d.appendleft('b') # 在最左边添加一个元素,此时 d=deque(['b', 'a'])
d.extend(['c','d']) # 在最右边添加所有元素,此时 d=deque(['b', 'a', 'c', 'd'])
d.extendleft(['e','f']) # 在最左边添加所有元素,此时 d=deque(['f', 'e', 'b', 'a', 'c', 'd'])
d.pop() # 将最右边的元素取出,返回 'd',此时 d=deque(['f', 'e', 'b', 'a', 'c'])
d.popleft() # 将最左边的元素取出,返回 'f',此时 d=deque(['e', 'b', 'a', 'c'])
d.rotate(-2) # 向左旋转两个位置(正数则向右旋转),此时 d=deque(['a', 'c', 'e', 'b'])
d.count('a') # 队列中'a'的个数,返回 1
d.remove('c') # 从队列中将'c'删除,此时 d=deque(['a', 'e', 'b'])
d.reverse() # 将队列倒序,此时 d=deque(['b', 'e', 'a'])```
队列
1.优先队列
优先队列通过堆数据结构,而堆是一种完全二叉树,他会对进入容器的元素进行排序(根据事先指定的规则),出队的顺序则会是二叉树的根节点代表的元素。
https://www.yangyanxing.com/article/priorityqueue_in_python.html
heapq是一个二叉堆得实现,它内部使用内置得list对象,它无论插入还是获取最小元素复杂度都在O(log n)。这里主要用到他的 heappush 与 heappop方法,heappush方法需要传入两个参数,一个是列表(list),另外是一个对象,这里的对象需要是可以比较的对象,就是它可以通过cmp方法来比较大小,以下是在python2中得代码实现:
import heapq
tasks = []
heapq.heappush(tasks,(10,'aaa'))
heapq.heappush(tasks,(40,'bbb'))
heapq.heappush(tasks,(30,'ccc'))
heapq.heappush(tasks,(20,'ddd'))
while tasks:
task = heapq.heappop(tasks)
print(task)
如果队列是空的:q是队列
if not q:
定义队列
queue = collections.deque()
queue.append(root)
集合
集合元素得添加:
s = {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’}
s.add(‘3’)
print(s)
集合的定义:
full = set()
##数学定理
1.同余定理:数论中重要概念。给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,那么就称a与b对模m同余,记作 a(三横线)b。对模m同余是征数的一个等价关系。
证明很简答,就是两个数对m都有相同的余数的时候做差能够把余数减掉了。
同余定理是初等数论的重要组成部分
##刷题整理
同一道题的变种: 560,974,1590
##哈希表
散列表(Hash table),也称为哈希表,是根据关键码(Key和value)而直接进行访问的数据结构。也就是说,他通过把关键码值映射到一个表中一个位置来访问记录,以加快查找的速度,这个映射函数叫做散列函数,存放记录的数组叫做散列表
给定表M,存在函数F(key),对任意给定的关键字值Key,代入函数后若能得到包含该关键字的记录在表中的地址,则称为哈希表
与列表不同,哈希表的索引是Key,直接通过Key值访问value,而不同于列表,通过整数[0,正无穷]作为索引存储值
字符串
第58题:
“\s+” 可以表示一个或多个空格
s = s.strip() # 删除首尾空格
返回:
res = [‘123’,‘dfd’,‘dfd’]
print(’ '.join(res))#用空格连接返回
如果不是字符串 返回0
if not str: return 0
数字的拼接:
res = 10 * res + ord© - ord(‘0’) # 数字拼接
每次乘10进位,ord是用ASCII码把字符转化为相应的数字
二叉树
1.二叉树的深度:
leetcode111:
给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
思路:当前结点作为root结点
1.若root两个节点都不存在,则返回1
2.若root左右节点只有一个存在,以左右存在的那个节点当root返回值加1
3.若root左右节点都存在,则左右节点路径最小的返回加1
终止条件,当左右节点都不存在的时候返回1,这是极端情况也是终止情况
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root: return 0
res = 0
if not root.left and not root.right:
res = 1
elif root.left and root.right:
res = min(self.minDepth(root.left),self.minDepth(root.right)) + 1
elif root.left:
res = self.minDepth(root.left) + 1
elif root.right:
res = self.minDepth(root.right) + 1
return res
2.左根右的二叉树中序遍历,能够保证输出的序列非递减
leetcode 671
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def __init__(self):
self.max_counter = 0
self.pre = float("-inf")
self.counter = 0
def findMode(self, root: TreeNode) -> List[int]:
res = []
def dfs(root):
if not root:
return []
dfs(root.left)
if root.val == self.pre:
self.counter += 1
else:
self.counter = 0
self.pre = root.val
if self.counter> self.max_counter:
self.max_counter = self.counter
res.clear()
res.append(root.val)
elif self.counter == self.max_counter:
res.append(root.val)
dfs(root.right)
dfs(root)
return res
循环遍历: 当 queue 为空时跳出。
初始化一个空列表 tmp ,用于临时存储下一层节点;
遍历队列: 遍历 queue 中的各节点 node ,并将其左子节点和右子节点加入 tmp;
更新队列: 执行 queue = tmp ,将下一层节点赋值给 queue;
统计层数: 执行 res += 1 ,代表层数加 11;
树的遍历方式分为两类,深度优先搜索(DFS)和广度优先搜索 (BFS)
常见的DFS: 先序遍历,中序遍历,后序遍历
常见的BFS:层序遍历(即按层遍历)
求树的深度需要遍历树的所有节点,本文将介绍基于 后序遍历(DFS)和层序遍历(BFS)的两种解法
深度后续遍历:
1.树的后续遍历用递归或栈实现,本文使用递归实现
2.关键点:此树的深度和其右子树之间的关系,显然,此树的深度等于左子树的深度与右子树的深度中的最大值 +1
计算节点root 的左子树的深度,即调用 maxDepth(root.left)
计算节点root的右子树的深度,即调用 maxDepth(root.right)
树的深度即为: max(maxDepth(root.left),maxDepth(root.right))+1
层序遍历 (32I,32II)
1.使用队列实现
2.每遍历一层,则计数器+1,直到遍历完成,则可得树的深度
3.按层打印:题目要求的二叉树的从上到下打印(即按层打印),又称为二叉树的 广度优先搜索(BFS),BFS通常借助队列实现,因为队列具有先入先出的特性。
4.每层打印到一行:将本层全部节点打印到一行,并将下一层全部节点加入队列,以此类推,即可分为多行打印。
思路:
(1)特例处理,当根节点为空,则返回空列表 []
(2) 初始化:打印结果列表 res = [] ,包含根节点的队列 queue = [root]
(3) BFS循环,当队列queue为空时跳出
1.新建一个临时列表 tem,用于存储当前层打印结果
2.当前层打印循环:循环次数为当前层节点数(即队列queue的长度)
1.出队:队首元素出队,计为node
2.打印:将node.val添加至tmp的尾部
3.添加子节点:若node的左右子节点不为空,则将左右子节点加入队列queue
3.将当前层结果 tmp 添加到 res
4.返回值 res
剑指offer 24 反转链表
主要思路 双指针,一个指向头结点 一个指向为节点,先把头结点指向为节点,在把头指针后移,尾指针后移,再把头指针指向尾指针,重复这个过程
二叉树的中序遍历顺序为 左 根 右 这个顺序是递增的数组顺序
二叉树的倒序中序遍历的顺序为 右 根 左, 这个顺序是递减的数组顺序
与运算与移位
n&1 ==0 判断n的最后一位是0
n&1 ==1 判断n的最后一位是1
这种与运算能够判断一个数字最后一位
对于n右移一位的运算为 n>>=1
数据的类型
type(x) == complex 说明数据是复数的形式