算法
English_yang
这个作者很懒,什么都没留下…
展开
-
算法:数论(质数与质因子)
1、试除法求质数import mathdef div(x): q=int(math.sqrt(x)) for i in range(2,q+1): if x%2==0: return False return True2、分解质因数(试除法)import mathdef div(x): q=int(math.sqrt(x)) left=2 while left<=x/left i原创 2021-08-24 23:15:51 · 343 阅读 · 0 评论 -
算法:最小生成树和二分图
仅仅用于无向图:Prim算法(朴素):一般用于稠密图克鲁斯卡尔算法:用于稀疏图原创 2021-08-11 22:45:37 · 181 阅读 · 0 评论 -
算法:动态规划(其他dp)
计数dp:leetcode413.等差数列划分class Solution: def numberOfArithmeticSlices(self, nums: List[int]) -> int: #dp[i]表示以num[i]结尾的等差数列的个数,可以看出dp[i]可以从dp[i-1]推来, #例如:[1,2,3]---dp[2]=1而[1,2,3,4]以4结尾的等差数列个数为dp[3]=2, #一个是dp[2]的延续,个数即d.原创 2021-08-10 13:45:47 · 379 阅读 · 0 评论 -
算法:动态规划(背包问题)
①常用模型:背包问题②线性DP、区间DP、计数DP;0-1背包N个物品,容量为V的背包,每个物品体积为vi,价值为wi,每件物品最多一次。在背包装得下的情况下,价值之和最大是多少?状态表示:f(i,j)表示从前i个物品中选,总体积小于等于j的最大值。最终要的是f(N,V)状态计算:集合划分完全背包N个物品,容量为V的背包,每个物品体积为vi,价值为wi,每件物品有无限个。在背包装得下的情况下,价值之和最大是多少?多重背包N个物品,容量为V的背包,每...原创 2021-08-07 15:42:51 · 245 阅读 · 0 评论 -
算法:最短路
朴素迪杰斯特拉算法(适用于稠密图): S:当前已经确定最短距离的点的集合①初始化距离。dis[1]=0 其余正无穷②for v :0~n: 不在S中的距离最近的点t t放入s中 用t更新其他点的距离#n为节点个数、g为邻接矩阵、dis为距离1号点的距离、st表示是否已经确定最短路径#初始化N=510 #节点总数,看题目g=[[float('inf')]*N for _ in range(N)]st=[False]*N#...原创 2021-08-04 20:02:12 · 129 阅读 · 0 评论 -
数据结构:堆
如何手写一个堆?1、插入一个数; size+=1;heap[size]=x ;up(size)2、求集合当中的最小值;heap[1];3、删除最小值;heap[1]=heap[size] ; size-- down(1);4、删除任意一个元素;heap[k]=heap[size]; size--;down(k);up(k)5、修改任意一个元素;heap[k]=x;down(k);up(k)堆是一棵 二叉树!存储方式:一维数组存储x的左儿子:2x;右儿子:2x+1,1为...原创 2021-08-02 16:13:42 · 77 阅读 · 0 评论 -
数据结构:并查集
快速处理如下问题: 1、将两个集合合并; 2、询问两个元素是否在一个集合中。基本原理:每个集合用一颗树来表示。树根的编号就是整个集合的编号。每个节点存储它父节点,p[x]表示的父节点。如何判断树根? if(p[x]==x)#父亲等于自身,就是根如何求集合编号?while(p[x]!=x)x=p[x]如何合并两个集合:px为x的集合编号,py为y的集合编号,p[x]=y,两个树的根连一下。会加路径压缩优化p=[0]*1000010#数组模拟def...原创 2021-08-02 15:26:31 · 138 阅读 · 0 评论 -
数据结构:Trie树
Trie树:用来快速存储和查找字符串集合的数据结构。数组模拟Trie树N=100010#所有字符串总长度,自己定义s=[[0]*26 for i in range(N)]#定义N*26的数组,N表示节点数量,后面的26维表示孩子ct=[0]*N #用于记录单词出现个数idx=0#全局变量,用于标记当前操作到了哪一个字符def insert(word):#将word插入tire树 p=0 for i in range(len(word)): num=ord原创 2021-08-02 10:04:42 · 84 阅读 · 0 评论 -
算法:最长公共子串和最长公共子序列
最长公共子串'''最长公共子串dp问题dp[i][j]表示str1[:i]与str2[:j]最长公共子串的长度'''def LCS_s(str1,str2):#返回最长公共子串长度 m=len(str1) n=len(str2) dp=[[0]*(n+1) for i in range(m+1)] max_len=0 for i in range(1,m+1): for j in range(1,n+1): .原创 2021-08-01 10:59:25 · 232 阅读 · 0 评论 -
算法:回文系列(二维dp总结)
①求最长回文子串:#dp[i][j]表示原数组i到j之间是否构成回文串#dp[i][j]=dp[i+1][j-1] 可见要求i,j,首先要知道i+1位置的j-1,这样就决定了循环的次序!#对于字符串s,长度为n。max_=0#全局变量,记录最大值dp=[[False]*n for i in range(n)]for j in range(1,n): for i in range(j+1):#这样循环,在dp[i][j]的时候肯定是知道了dp[任意][j-1]的值了原创 2021-07-31 22:17:50 · 238 阅读 · 0 评论 -
数据结构:KMP算法
过程略;注意next数组的含义,next[i]表示以i为终点的后缀和以1为开始的前缀相等,且后缀长度最长。即如果next[i]=j 那么原始数组p[1~j]=p[i-j+1,i]背模板:n=int(input())p=' '+input()#模板串(加空是为了下标从1开始)m=int(input())s=' '+input()#原串(加空是为了下标从1开始)N=100010ne=[0]*N#next数组#求next数组j=0#前缀==后缀的长度即对于i位置而言,p[1~j]=原创 2021-07-31 22:12:32 · 116 阅读 · 0 评论 -
数据结构:栈和队列
栈:先入后出队列:先入先出数组模拟栈:tt=0#标记栈顶stk=[0]*N#定义大小为N的数组#x入栈---------------------------------------------------:tt+=1stk[tt]=x#出栈---------------------------------------------------:tt-=1#取栈顶元素---------------------------------------------------:stk[tt原创 2021-07-31 16:56:07 · 100 阅读 · 0 评论 -
基础算法:区间合并
[1,3]and[2,6]合并为[1,6], 将[1,3]和[3,7]合并为[1,7]将有交集的区间进行合并。输出合并后区间的个数:如上图,合并后为3。做法:①按照区间的左端点排序。②扫描整个区间,把所有有可能有交集的合并。res=[]#存放结果data=[[1,3],[2,4],[7,8]]data.sort(key=lambda x:x[0])#按照第一个元素排序i=0while i<n: left=data[i][0] right=data.原创 2021-07-29 16:31:59 · 190 阅读 · 0 评论 -
基础算法:离散化(整数)
离散化:有一堆数字,但是他们差别很大,如:1,2,100,5000,1555555,但是我们想把他们当作下标来使用。不可能去开一个1555555的数组,想把他们映射到1,2,3,4,5这样的区间上。如何得到?即如何得到x离散化后的结果?做法:1、给原始的A数组排序后去重;2、二分查找即可。#a为原始数组a.sort()a=list(set(a))#去重def find(x): ''' 二分求出第一个大于等于x的位置,就是x的位置 得到x离散化之后的位置原创 2021-07-29 15:34:24 · 270 阅读 · 0 评论 -
基础算法:位运算
常用的位运算操作:n的二进制表示中第k位数字是几?① 先把第k位移动到最后一位:n>>k② 看个位是几n&1比如:输出n的每一位:n=10for k in range(4,0,-1): print(n>>k&1)n>>k&&1负数的二进制:-x=~x+1lowbit操作:x&-x 作用是只保留二进制的最后一个1 即 01011000通过lowbit操作之后就变成了1000通...原创 2021-07-29 14:41:51 · 138 阅读 · 0 评论 -
基础算法:差分
差分是前缀和的逆运算。给定: 要构造数组,使得.即数组a中的每个元素是b数组的前缀和。构造方法:...数组b就称为a的差分数组。要是想给a数组的[l,r]这一段每个元素都加上c,那么操作b的话只需要操作b[l]+c,b[r+1]-c即可。因为a为b的前缀和,b[l]+c会导致a[l:]都加上c,补上一个b[r+1]-c就可以让a[r+1]恢复正常,使得a[l,r]都加c完毕。具体的,对于a,可以全部初始化为0,然后对于0位置,让[0,0]全部加上真实.原创 2021-07-28 19:33:45 · 155 阅读 · 0 评论 -
基础算法:前缀和
前缀和数组: 下标一般从1开始。①怎么求?s[0]定义为0.for i in raneg(1,len(a)): s[i]=s[i-1]+a[i]②有什么用?可以快速求出数组中一段数字的和~~~比如要求一个数组中[left,right]之间的数字和:即可简单的例子:if __name__=='__main__': n,m=map(int,input().split()) res=list(map(int,input().split()))...原创 2021-07-28 16:07:25 · 85 阅读 · 0 评论 -
基础算法:高精度
高精度运算指大数运算,python中数字没有位数限制,所以其实用不到高精度运算,但是可以当作练习,用于计算如[1,2,3,5]+[7,9,5,7,8]等得到的结果。高精度加法:def add(a,b): ''' a,b为按照逆序存储的列表,因为计算的时候会先算个位,所以逆序存放 ''' res=[]#存放结果 t=0#记录进位 left=0 while left<len(a) or left<len(b): if原创 2021-07-28 12:33:47 · 108 阅读 · 0 评论 -
基础算法:二分(Python)
二分查找模板:模板一:def Binary_Search(res,data): ''' 在res中查找值为data的元素 ''' left=0 right=len(res)-1 while left<right: mid=left+right>>1 if (check(res[mid])):right=mid else:left=mid+1 return left模板二:原创 2021-07-27 16:48:04 · 433 阅读 · 1 评论 -
基础算法:归并排序(Python)
对数组进行归并排序:def merge_sort(res,l,r): if l>=r: return mid=l+r>>1 merge_sort(res,l,mid) merge_sort(res,mid+1,r) #下面就是合并两个有序数组 left=l right=mid+1 data=[] while left<=mid and right<=r: if res[原创 2021-07-27 10:05:35 · 129 阅读 · 0 评论 -
基础算法:快速排序(Python)
模板一(不需要新建空间)def quick_sort(res,l,r): if l>=r: return left=l-1 right=r+1 mid=res[l+r>>1] while left<right: while True: left+=1 if res[left]>=mid: break原创 2021-07-27 08:55:44 · 203 阅读 · 1 评论