![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
guofei_fly
这个作者很懒,什么都没留下…
展开
-
【动态规划】最大公共子序列和最大公共子串
"""DP法求解最大公共子序列问题:求string1和string2中最长的公共子序列(可不连续)的长度中间状态 M[i,j]表示截至到string[i]和string[j]的序列长度"""def max_cls(string1, string2): M = [[0 for _ in range(len(string2)+1)] for _ in range(len(string1)+1)] # string前补充初始位,值默认为0 for i in range(len(原创 2020-07-21 23:43:56 · 617 阅读 · 0 评论 -
【动态规划】最短编辑距离
"""采用DP算法实现最小编辑距离状态变量:M[i][j] 截至到string1的第i个字符和string2的第j个字符,改为一样的所需的编辑距离"""def MED(string1, string2): M = [[0 for _ in range(len(string2)+1)] for _ in range(len(string1)+1)] for i in range(len(string2)+1): M[0][i] = i for j in r原创 2020-07-21 23:42:12 · 248 阅读 · 0 评论 -
【图】用python实现有向图的DFS
# 1. 创建Vertex对象class Vertex(object): """ 节点对象,在基础节点对象的基础上,添加了关于着色、前驱节点以及距离的相关属性和方法 """ def __init__(self, key): self.key = key self.connectedTo = {} # 存放指向的其它节点,以Vertex:连接边weight的 self.color = "white" # BFS中的状态原创 2020-07-21 23:41:05 · 1832 阅读 · 0 评论 -
【剑指offer】剪绳子
【题目】给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。显然,可以尝试着将问题规模减小并挖掘不同规模问题间的关系。思路一: 将f(n)转变为max(f(n-i)*i)问题,其中i为切分的那段长度为i根据这个思路,可分别写出对应的递归方法、带备忘的递归方法以及DP方法。原创 2020-06-25 15:54:59 · 264 阅读 · 0 评论 -
【最优二叉树】Huffman树
Huffman树,又称作最优二叉树,是一种用于信息编码的数据结构。其通过对比各元素的频率/数量,自底向顶构建一颗二叉树,频率越低的元素越在底部。在Huffman树中,所有元素均为叶子节点,而中间节点和根节点用于记录两颗孩子节点频次和,从而避免编码过程中可能存在的共用前缀的问题。Huffman树具备如下的基本功能和属性:(1)构建:基于元素频率,自底向顶构建最优二叉树;(2)编码:从root开始,设定左为0,右为1,沿着路径进行编码,可以证明这种编码形式是信息量最优的编码。根据Huffman树的基本属原创 2020-06-19 22:10:12 · 974 阅读 · 0 评论 -
【字典树】用python实现Trie树
字典树常用做高效的文本词语保存,适用于敏感词过滤、关键词提取等场景。在字典树中相同前缀的词之间共享相同的树节点和路径。字典树结构一般包括如下功能和属性:(1)构建;(2)添加;(3)删除;(4)前缀统计;(5)搜索实现一:通过字典的嵌套来实现class Trie(object): """ 实现1:通过python自带的字典结构 具有如下基本功能: (1)根据一组words进行TrieTree的构建 (2)添加某个word (3)查询某个word原创 2020-06-19 22:02:28 · 2092 阅读 · 2 评论 -
二分搜索及其问题拓展
二分搜索是适用于有序数组的高效搜索方式,本文先介绍二分搜索的递归和非递归形式,然后将其拓展到类似问题。1. 二分搜索的基本实现1.1 递归实现1.2 非递归实现2. 二分搜索的问题拓展2.12.2 模糊边界问题...原创 2020-06-17 22:47:08 · 210 阅读 · 0 评论 -
【动态规划】数组最长上升子序列问题(LIS)
相较于最长上升子串问题,LIS问题并不严格要求连续的子串,其求解难度也有所提升。在尝试将该问题由nnn规模缩减时,我们不光要考虑n−1n-1n−1规模的,还需要考虑所以更小规模的子问题。因为对于任何位置结尾的最长子串,无法确定其上一个数字在原始数组的什么位置。据此,我们定义如下的状态变量和状态转移函数。状态变量dp[i]: 以数组nums[i]为结尾的最长子串长度状态转移函数: dp[i]=max(dp[j]+1,1)ifj<i&nums[j]<nums[i]dp[i]=\ma原创 2020-06-16 22:30:46 · 450 阅读 · 0 评论 -
【动态规划】上升数组中的最长上升子串问题
所谓的上升子串,要求子序列连续。如对于[3,2,4,5,3,6] ,应当返回3,对应的最长子串为[2,4,5]。定义状态变量dp[i]:包括nums[i]在内的最长子串长度。状态转移函数: 如果nums[i]>nums[i−1]nums[i]>nums[i-1]nums[i]>nums[i−1]则dp[i]=dp[i−1]+1dp[i]=dp[i-1]+1dp[i]=dp[i−1]+1;否则dp[i]=1dp[i]=1dp[i]=1def maxAscendingArray(arra原创 2020-06-16 22:10:33 · 498 阅读 · 0 评论 -
【链表】寻找、删除单向链表的倒数第K个节点
通过设置快、慢两个指针,可以通过一次遍历得到单向链表的倒数第K个节点。但两个问题有着较为明显的区别:(1)对于寻找倒数第K个节点,慢指针慢于快指针第K-1步前进。(2)对于删除倒数第K个节点,为了保证得到删除节点父节点的信息,慢指针要慢于快指针第K步前进。(3)两者均要注意当链表长度不足时边界条件的定义。对于删除问题,尤其要注意删除第一个元素(倒数第N个)时,链表head指针的调整。# 定义单向链表class Node(object): def __init__(self, value)原创 2020-06-15 21:44:42 · 368 阅读 · 0 评论 -
【数组】旋转数组的搜索问题
旋转数组是指在原有顺序数组基础上,以某个未知点进行了旋转。以升序数组为例,其旋转后有三种基本形态(见下图,图中虚线为数组中心位置):情况一:未旋转情况二:旋转点位于中心位置右侧情况三:旋转点位于中心位置左侧。利用二分法可以以O(logn)(O(logn)(O(logn)(的时间复杂度在旋转数组中进行搜索。解决此类的问题,需要注意如下几点:(1)除情况1外,旋转数组以最高点为分割,左右两侧的部分从左到右都为升序(原始数组为升序数组);(2)通过mid点与low点或high点的大小,来进行形态的分原创 2020-06-14 16:27:13 · 309 阅读 · 0 评论 -
python中的对象与引用
在python中万物皆为对象,包括变量、函数、类以及其实例化的对象。python中所谓的赋值其实传的是对象指向的引用,也就是说传的是地址。1. 可变变量和不可变变量python中存在两大类型的对象,不可变对象(如基本类型中的元组、字符串、数值)和可变对象(如基本类型中的列表、字典、集合)。对于不可变对象,我们可以理解为存在于连续内存空间的统一整体,其同生共死,不可修改。而对于可变对象,我们可以理解为其每个元素实质上为对应不可变对象的引用,如果存在可变对象的嵌套,则重复引用直至最深层的不可变对象。原创 2020-06-06 11:57:33 · 2471 阅读 · 3 评论 -
【图】用python实现有向图的BFS
宽度优先搜索(BFS)是一种有效的图遍历方法,类似于二叉树的层遍历,其从初始搜索节点开始,逐层的往外扩散,特别适用于寻找两个节点间的最短距离等问题。在BFS过程中,需要引入队列结构。在探索某节点时,将相邻节点依次入列;探索完后,再将这些节点依次出列,从而实现遍历的层次化。因此,对某个节点,其存在三种状态:(1)未探索阶段;(2)作为相邻节点入列,待探索节点;(3)探索完(即将其所有的相邻节点入列)后的阶段。不同于二叉树的单向父子关系,无向图或有向图中均可能出现两邻接节点的双向指向关系。为了防止遍历过程中原创 2020-06-06 23:48:57 · 1164 阅读 · 0 评论 -
【图】用python实现有向图
通过临界表的方式实现了图结构class Vertex(object): """ 节点对象 """ def __init__(self, key): self.key = key self.connectedTo = {} # 存放指向的其它节点,以Vertex:连接边weight的 def addNeighbor(self, nbr, weight): self.connectedTo.update({nbr:原创 2020-06-06 15:33:09 · 9249 阅读 · 0 评论 -
【二叉树】用python实现AVL树
AVL树是平衡的二叉搜索树,其任意节点的平衡因子(左子树高度-右子树高度)始终为-1、0或1。AVL树的结构能够解决普通BTS由于有序插入导致的退化为链表的情况。AVL树在二叉搜索树实现的基础上,主要在添加和删除节点时更新子树相关节点的平衡因子,同时对不平衡的子树进行旋转操作。其机制较为复杂,本文先介绍相关的背景知识,在做代码的实现。1. 背景知识1.1 节点平衡因子的调整顺序与普通二叉搜索树不同的是:添加节点后相关节点的平衡因子因做出调整。其基本规则包括:(1)若该节点为左节点,则其父节点的平衡原创 2020-06-03 22:45:23 · 1444 阅读 · 3 评论 -
【二叉树】用python实现二叉搜索树
二叉搜索树(BTS, binary search tree)是满足左子树节点小于根节点、右子树节点大于根节点的二叉树,是B-树的特例,也是AVL的基础。本文实现了BTS的插入、查找、删除、遍历、最大/小值节点、前/驱驱查找等基本功能。1. 定义树节点类"""二叉树由各节点链式构成,节点中保存了键、值、左节点指针、右节点指针、父节点指针等信息。二叉树的遍历本质上为Node链上的遍历,因此可以利用__iter__和yeild方法实现遍历迭代器。节点是否为根节点、叶节点或者中间节点(包括父节点和左右节点原创 2020-05-31 11:26:41 · 1129 阅读 · 0 评论 -
【二叉堆】实现最小堆和最大堆
最小堆和最大堆采用完全二叉树的形式来存储不同数字的序列,在topK问题中有广泛应用。其满足中间节点大于左子树和右子树上所有节点值的特点,为保证其存储、查找和删除的遍历,通常采用数组的形式进行构建。本文实现了最小堆和最大堆的构建、堆顶查找、堆顶删除、插入等基本功能。最小堆class minBinaryHeap(object): def __init__(self): self.heap = [0] self.length = 0 def isEmpt原创 2020-05-30 11:52:28 · 446 阅读 · 0 评论 -
【二叉树】用python实现二叉树的遍历
二叉树有三种常见的遍历方式:前序遍历:按照根—>左——>右的递归方式进行遍历中序遍历:按照左—>根——>右的递归方式进行遍历后序遍历:按照左—>右——>根的递归方式进行遍历...原创 2020-05-29 00:01:31 · 835 阅读 · 0 评论 -
【排序算法】用python实现常见的排序算法
目前实现了冒泡排序、选择排序、插入排序、希尔排序、归并排序和快速排序等常见算法。1. 冒泡排序通过两层循环实现排序,每轮内循环实现外层子序列中最大/最小值的浮出。def bubbleSort(nums:list): for i in range(len(nums)-1): for j in range(i+1, len(nums)): if nums[j] < nums[i]: nums[i], nums[j] =原创 2020-05-24 16:34:35 · 156 阅读 · 0 评论 -
【链表】用python实现单向链表
from typing import Any, Optionalclass Node(object): def __init__(self, value: Any, next: Optional["Node"]=None): self.value = value self.next = next def __repr__(self): return f"Node({self.value})"class LinkedList(obje原创 2020-05-22 21:40:36 · 235 阅读 · 0 评论 -
【双端队列】用python实现双端队列
分别用有序列表和链实现了双端队列,主要包括首端加入/删除、末端加入/删除等功能。方法一:有序列表的实现class Deque(object): def __init__(self): self.data = [] def __repr__(self): return str(self.data) def addRear(self, value): self.data.append(value) def addFront原创 2020-05-20 22:22:54 · 598 阅读 · 0 评论 -
【队列】用队列模拟打印机的等待时间
用于打印机任务的仿真:一段时间内,打印任务和打印机状态的模拟构造三个对象:(1)打印机:实现了打印机的打印速度、剩余打印时间、打印任务三个属性,以及是否闲置、开启一项新任务和打印三个方法(2)打印任务:实现了任务的随机生成、任务量的生成、等待时间统计(3)打印队列:实现了打印任务的入列和出列操作,从而完成了打印任务和打印机之间的交互以时间(每秒)为单位,依次进行:1)是否生成新的打印任务;2)若生成新任务的话,入列;3)查看打印机状态;4)若打印机闲置,队列有任务的化出列进行打印;5)打印机有任原创 2020-05-20 21:55:13 · 577 阅读 · 0 评论 -
【队列】用python实现队列
分别采用有序列表、单链表和双链表实现了队列的基本功能,涵盖入列、出列等。方法一:基于有序队列的实现class Quene(object): def __init__(self): self.data = [] def __repr__(self): return f"Quene({self.data})" def enquene(self, value): # 入队列 self.data.append(value原创 2020-05-19 23:05:34 · 414 阅读 · 0 评论 -
【栈】用python实现栈
分别采用有序列表、单向链和双向链实现栈的推入、弹出等功能。方法一:有序列表的实现# 直接利用python内置的list实现class Stack(object): def __init__(self): self.stack = [] def push(self, item): self.stack.append(item) def peek(self): if self.isEmpty(): rais原创 2020-05-19 21:36:14 · 273 阅读 · 0 评论 -
使用栈构造后缀表达式解决简单的四则运算问题
对于四则运算表达式,中缀表达式是方便人类读懂的书写方式,而要转化为计算机方便计算的形式必须将其转换为前缀或者后缀表达式。本文利用栈结构简单数学四则运算表达式的计算,其中仅考虑四则运算和( ),同时不考虑错误表达式的排查。def RPN_express(m): """ 构造一个数字栈和一个符号栈,符号栈在如下情况下弹出压入数字栈: (1)遇到')',将'('之间的四则符号弹出 (2)每一个四则符号压入前,符号栈内等级更高的符号需弹出 @param: m 数学表达式原创 2020-05-14 23:50:48 · 179 阅读 · 0 评论 -
【算法实例】股票收益最大问题
问题描述:在T+1交易规则下,给出每天股票的买/卖价序列,要求在序列期间内最多只允许买、卖各一次,求此期间内的最大收益是多少(可以选择不卖,即收益为0)比如:(1)价格序列为[7,1,5,3,6,4],则最大收益为5,即选择第2天买入(买入价1)、第5天卖出(卖出价6)(2)价格序列为[7,6,4,3,1],则最大收益率为0,即只能选择买入,但因为价格持续下降,所以无法卖出。方案一:显然可...原创 2020-04-16 12:16:34 · 2282 阅读 · 0 评论 -
动态规划法求解硬币划分问题
硬币划分问题指:给定一些基础硬币(如1、2、5元),最少需要多少枚硬币能够划分能够凑成目标的金额。思路一:递归法从大——>小进行逐层分解,递归求得所有的划分可能性,然后取得其中数量最少的划分方案。# 这里只给出所有可能的划分方案,剩下的求元素数量或最优方案需做后处理# 按照这里给出方案,每次分解硬币的顺序也是区分的def split_coins(total: int, coins:...原创 2020-04-05 17:26:41 · 822 阅读 · 0 评论 -
动态规划法求解最长上升子串问题
问题描述: 给出一个array的数值(有正有负),给出一个最长的上升子串(可以不连续)的长度定义子状态: m[i]m[i]m[i]表示以数组元素A[i]A[i]A[i]结尾的最长上升子串的长度状态转移关系:m[j]=maxi<j,A[i]<A[j]m[i]+1m[j]=\max \limits_{i<j,A[i]<A[j]}m[i]+1m[j]=i<j,A[i]...原创 2020-04-05 11:32:14 · 240 阅读 · 0 评论 -
动态规划法求解最大子序列和问题
问题描述:给出一个数字array(其元素值可正可负),求其连续子序列中,各元素和的最大值(不要求子序列的长度)定义子状态:m[i]m[i]m[i]表示以数组元素A[i]A[i]A[i]结尾的最大子序列之和状态转移关系:m[i+1]=max{m[i]+A[i+1],A[i+1]}m[i+1]=\max\{m[i]+A[i+1], A[i+1]\}m[i+1]=max{m[i]+A[i+1],A...原创 2020-04-05 10:52:11 · 514 阅读 · 1 评论 -
适用于分词的前向/后向最大匹配算法
字符串最大匹配算法是建立在词典表基础上的,用于字符串分词的经典算法。根据字符串扫描的方向,可分为从前往后的前向最大匹配算法、从后往前的后向最大匹配算法,以及两者均做然后采取某些策略进行取舍的双向最大匹配算法。字符串最大匹配算法采用了典型的贪心思想,在字符串扫描过程中,沿着既定方向不断增加长度的扫描,并与词典表上对照以找到最长的匹配子串作为当前的分词结果。但若不设置阈值,每轮扫描都会继续到字符串末...原创 2020-04-03 22:22:27 · 1040 阅读 · 0 评论 -
利用递归思想解决N-皇后问题(个人理解)
N-皇后问题是可用回溯法解决的经典案例。而回溯法本质上基于递归思想,对所有可行的方案分支进行深度优先的探索,而对于验证失败的分支回溯到其他可能分支,或全部验证失败后pass。本文将N-皇后问题进行拓展,衍生为M×NM\times NM×N棋盘布局下的布局问题,各棋子间不能同行、同列或对角线。当M=NM=NM=N时,即为严格意义上的N-皇后问题。回溯法,或者更广义意义上的递归法的关键在于明确如下...原创 2020-03-28 10:27:35 · 859 阅读 · 0 评论