基础算法学习笔记

deepseek

解决算法问题的思路:
1、枚举
(核心问题:1.避免无用的组合可以减少枚举的次数 2.找到枚举的规律 3.是否存在一个局部,一旦这个局部确定,其他部分也确定了)
2、递归
(核心问题:1.后一项依赖前一项的结果,如等差、等比数列 2.从大到小考虑 3.本身问题的定义包含递归,如A的定义用到了自身A,并且包含终止条件 4.将递归问题分解成更小的字问题求解)
可以用递归的写法一般都可以用死循环while 写

3、二分查找
(核心问题:1.凡事按顺序大小查找的程序都可以用二分查找优化)
只要看到面试题里给出的数组是有序数组,都可以想一想是否可以使用二分法。
明确区间定义【】左闭右闭 ,
while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
如果想确定中间的插入位置就是right+1
如果想确定左右上界,排除初始值(-2开始),分别为 left+1 和 right-1,也可以局部遍历

4、移动元素
双指针法
1、快慢指针(遍历快指针,逐个赋值,遇到特殊情况跳过)
移除元素可以直接交换,仅去除重复在后1个位置交换
移除或删除回退可以反向变量数组,可以避免数组长度变化的问题 del nums[index]
或新申请一个数组保留结果
renums = []
renums.append(val)
nums[:len(renums)] = renums
2、相向指针(遍历left指针,遇到特殊情况赋值)写起来比快慢指针要复杂
3、双指针还可以用于滑动窗口、比如求和,求乘积等
如果两个循环的复杂度跟一个循环相同,尽量用两个循环写。逻辑更简单
字典声明dict(),带默认值的字典函数,defaultdict(int),判断是否存在 x in d1 或 not in ,元素个数len(),删除元素 del my_dict[‘a’] 或 my_dict.pop(x)
数组操作:python 数组需要 数组间赋值,不能直接改为一个值
https://blog.youkuaiyun.com/m0_73633088/article/details/128859556
旋转数组,保证循环不变量原则,里面每次是减少2,反向循环尽量写的简单。按顺序循环
**一维数组声明: [0] * n
[0 for _ in range(n)]
二维数组声明 [ [0] * n for i in range(m) ]

用乘法声明数组是引用,更改数组内容可能出问题
matrix = [[0]*2]*2
数组转字符串 “”.join(list)

数组声明 [] renums.append(val)
列表合并 [] + []
二维列表元素放入[].append(list([1])) 或 [].append(L[:])
字典声明 dict() 或 {1:‘a’,2:‘b’ } 或 defaultdict(int) 或 defaultdict(list)
获取dict[x] ,dict.get(x,unknown) ,使用get可以避免空值报错
删除 del my_dict[x] 或 my_dict.pop(x)
获取dic 的dic,keys() 或dic,values() 如果放到list里就是list(dic,keys())
也可以直接放入指针节点最为key比如dict[ListNode]
字典中放入list,内存引用不可切换复制,在引用中操作 index_dict[key].append(value)
集合声明 set() 增加set1.add() 删除set1.remove()
队列 from collections import deque
deque[0] deque[-1] 可以用list代替
堆操作 import heapq ,第一个输入是list
heapq.heappop([])
heapq.heappush([],x)

5、链表
虚拟头需要遍历的指针指向head,如果是反转直接虚拟头为None 就可以
链表头直接是直接赋值别名,需要赋值后直接更新之前的节点
需要判空处理,如果是空节点查询其中的值会报错差不到

5、排序
python 默认排序函数 sorted(x) ,字符串排序完是数组
快速排序复习下

6、分治
(核心问题:1.把一个任务,分成形式和原任务相同,但规模更小的一个或几个部分任务,分别完成,处理完成后的结果)
归并排序、快速排序

5、动态规划
类型 (1)记忆递归型动归程序,直观简单
递归转动规的一般转化方法:从边界值向前推导,递归函数的逆过程。 速度更快,使用滚动数组节省空间
1)、递归的分析问题,分解成若干子问题,子问题和原问题形势相同,子问题保存结果避免重复计算。
2)、确定状态,某个状态下的值,对应字问题的解
3)、确定一些初始状态(边界状态)的值
4)、确定状态转移方程
能用动态规划解决的问题的特点。1)、问题具有最优子结构性质 2)、无后效性

6.深度优先搜索
寻找图上到一些节点的路径或多种可能性
遍历相邻节点,记录状态,递归遍历(可能性的去除状态)
剪枝:对已经知道结果的枝不在探索,记录下目前最优结果进行比较
可行性剪枝和最优性剪枝
1.深度优先搜索确定枚举
2.搜索的范围
3.搜索的顺序
4.如何剪枝

7.广度优先搜索
1.初始节点放入open队列
2.判断是否为空,为空没达到则无解
3.取出点放入close表
4.判断是否为目标节点
5.是否可扩展,不可扩展则返回第2步
6.可扩展则判重后放入open表尾部,返回第2步

8.贪心算法
在问题求解时,总是作出当前看来最好的选择。
贪心算法要求贪心策略具备无后效性,某个之前的状态不会影响以后的状态,及局部最优解为全局最优解
先排序在遍历

9、算法题
概率论:https://www.cnblogs.com/xianbin7/p/10690064.html
赛马比赛:https://zhuanlan.zhihu.com/p/79971028

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值