文章目录
有效的总结
- 代码随想录,内含一些常见的题目类型总结和刷题的代码
- 个人fork基础上的修改
牛客网输入代码
- 牛客上的输入需要自己写代码解析出来,和leetcode上直接写函数不一样。
- 解析输入的数组“2 3 4 5”
data = input().strip.split(' ')
data_list = list(map(int, data))
一些小bug
python的深拷贝和浅拷贝
- 对于a=b
- 深拷贝:开辟一块新的存储空间,修改一个的值,另外一个不会受影响,
a=b.copy()
,可以不考虑类型,强行深拷贝 - 浅拷贝:指向同一块区域,修改任意一个元素的值,另一个也会受到影响
行列初始化
grid = [[0]*3]*2 -----有共享的内存空间
grid[1][1] = 1
>>> [[0, 1, 0], [0, 1, 0]]
grid = [[0 for _ in range(3)] for _ in range(2)]--相当于for循环的每一步开辟一块新的空间
grid[1][1] = 1
>>> [[0, 0, 0], [0, 1, 0]]
不同类型
- a=b
- b如果是string, int, float都是深拷贝
- b如果是numpy矩阵,list,指针,都是浅拷贝
动态规划
解题步骤
- 定义状态:dp[i]指的是第i个元素的最大(最小)值是dp[i]
- 初始状态:dp[i]赋初值
- 转移方程:dp[i]和dp[i-1]或者其他元素之间的跳转关系;
- 最终结果:dp[i]中的什么元素对应最终返回的结果
二叉树
定义
- 完全二叉树:排布的时候必须先左子树
- 二叉搜索树:数值大小有序,left<root<right
- 二叉搜索平衡树:满足二叉搜索树有序条件的基础上,left_highth-right_highth <=1
遍历
前序遍历
- 先访问根节点。
- 然后递归遍历左子树。
- 最后递归遍历右子树。
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def preorder(root):
if not root:
return
res.append(root.val)
preorder(root.left)
preorder(root.right)
preorder(root)
return res
中序遍历
- 以中序遍历的方式遍历根节点的左子树。
- 访问根节点。
- 以中序遍历的方式遍历根节点的右子树。
class class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def inorder(root):
if not root:
return
inorder(root.left)
res.append(root.val)
inorder(root.right)
inorder(root)
return res
后序遍历
- 后序遍历左子树
- 后序遍历右子树
- 跟节点
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def postorder(root):
if not root:
return
postorder(root.left)
postorder(root.right)
res.append(root.val)
postorder(root)
return res
层序遍历
- 先遍历第一层节点
- 遍历第二层节点
- 重复 & 继续
- step1 : 队列queue,队列长度
- step2:在当前队列长度的情况下遍历队列,找到cur.val,存入有序序列order,找到cur.left,cur.right,加入队列中(把这一层所有节点的下一层叶子节点拿到)
- step3:更新队列长度,重复2
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
queue = [root]
order = []
while queue:
level = []
size = len(queue)
for _ in range(size):
curr = queue.pop(0)
level.append(curr.val)
if curr.left:
queue.append(curr.left)
if curr.right:
queue.append(curr.right)
if level:
order.append(level)
return order
BFS & DFS
BFS(breadth first search)广度优先搜索
- 使用队列结构,先进先出
- 逐层搜索,当搜索k节点的时候,将k节点的字节点加入队列;然后list.pop(0) ,首先弹出的是k节点的同层节点
- 参考二叉树的层序遍历
DFS(depth first search)深度优先搜索
- 使用栈结构,先进后出
- 当搜索k节点的时候,将k节点的字节点加入栈,注意节点加入的顺序,因为考虑先进后出,所以同级目录先加右节点,再加左节点
单调栈
对于「找最近一个比当前值大/小」的问题,都可以使用单调栈来解决。
单调栈就是在栈的基础上维护一个栈内元素单调。
链表
- 链表的结构cur.val, cur.next。只知道当前和下一个,不知道链表的长度
拓扑排序&有向无环图
- 只有有向无环图才能进行拓扑排序(拓扑排序的数据必然存在有向无环图),有向有环图无法进行拓扑排序。
- 考虑节点入度,出度。
排序问题
- 低阶排序:冒泡排序,
- 高阶排序:快速排序,堆排序,归并排序
数组中找出第k大的数字
快速排序:先找一个参考值mid(begin/end),划分数组,小于mid的排在前边,大于mid的排在后边,然后单独排前后两部分(归并问题)