![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构
文章平均质量分 60
萤火虫之暮
这个作者很懒,什么都没留下…
展开
-
哈夫曼编码的非树节点形式实现
哈夫曼编码的非树节点形式实现楔子思考过程于是想自己写一个headq构建二叉树实在太久了,完全不让看文档,不敢不相信在有限的时间里可以调试成功,于是就想了使用非树的实现方式,就是把手动画的二叉树,从树叶往上补充哈夫曼编码总结楔子今日心血来潮参加了某厂家的机试,牛客网上机试,一看只有一题且时间90分钟200分,允许使用本地IDE,就知道肯定几分钟出不来,看题目可喜的是秒懂哈夫曼编码,可悲的是一年半...原创 2020-04-18 20:50:34 · 385 阅读 · 0 评论 -
分治:分治和动态规划的区别,二分检索递归和迭代方式实现
分治法分治一般可以直接使用递归实现,在不考虑空间消费的情况下和迭代方式时间消耗相差不多==================================================================分治一般形式: T(n) = k*T(n/m) + f(n)k为子问题个数,一般均分或者等比分n/m问题规模,一般情况下m已经确认了子问题的个数,可以通过变换减少为a个f...原创 2018-12-11 11:55:01 · 828 阅读 · 0 评论 -
算法优化:最大m个子段和,问题规模从1个子段和扩展到m个,动态规划
最大m个子段和,问题规模从1个子段和扩展到m个,动态规划问题规模由2个决定,一是子段数m,二是元素个数n,准确的说是最后一个子段终止的标号b(i,j)定义为:前j个元素中有i个子段,且第i个子段包含j,i个子段和为b(i,j)那么原问题的最优解为max{b(m,j)},m<=j<=n还是不是针对原问题动态规划,动态规划的问题是可能解,最后在可行解里面找最优解根据b(i,j)定...原创 2018-12-16 17:13:34 · 1604 阅读 · 0 评论 -
树形结构:优先级队列,堆
优先级队列,堆是比较常用的数据结构,分支限界法,贪心法均会用到优先级队列有必要了解一下优先级队列的实现方式# -*- coding: utf-8 -*-# 最大堆# 很显然这是一个双针模型,指着一对父子,父亲小于儿子,则儿子上位def siftUp(arr,insert_index,insert_value): child_pointer = insert_index ...原创 2018-12-21 13:53:26 · 443 阅读 · 0 评论 -
算法优化:最大子段和,最大子矩阵和,一维,二维情况分析,动态规划
最大子段和,前面b[j]理解的是:终点在j的最大连续子段和,及从k:j最大和是对b[j]进行动态规划,从k:j最大和:取决于k:j-1的最大和,他大于0的话,就为k:j-1的最大和+arr[j],他小于0的话,就只是arr[j]终点在j一共有n种情况,原问题只是求b[j]的最大值从上面可以看出,终点在j的最大连续子段和这个还是很刁钻的,解决问题你不从原问题直接去分解,而去想“终点在j的最...原创 2018-12-16 13:18:16 · 700 阅读 · 0 评论 -
算法优化:最大字段和,双指针遍历(n^2),分治法(nlogn),动态规划(n)
最大字段和,有点类似与最长公共子序列,这里是求连续一段求和最大的一段,比如[-2,11,-4,-4,13,-5,-2]最大求和的连续一段为11,-4,-4,13,和为16.最基本的双针模型遍历,两个指针,分别代表最大和序列的起始和终止,算法时间复杂度O(n^2)# 以下算法时间复杂度O(n^2)def maxSum(arr): num = len(arr) # 记录最好的结果...原创 2018-12-15 16:50:23 · 704 阅读 · 0 评论 -
分治法:BFPTR算法找第k小
BFPTR算法来自于Blum、Floyd、Pratt、Rivest、Tarjan这5个人,一起发布了一篇名为 “Time bounds for selection” 的论文,有兴趣可以看一下:https://pan.baidu.com/s/1QEWjZBrjEJ7zTIrI99sFYA。下面是一种实现方式,这种有一个问题,只是找到中位数了,标号还要搜索然后此时的数组是有结构规律的,划分数组的时...原创 2018-12-15 12:37:37 · 305 阅读 · 0 评论 -
树形结构:使用栈实现,快排,先序遍历,归并排序,后序遍历
主要还是学习使用栈模拟实现递归:# -*- coding: utf-8 -*-def partition(arr,low,high): # 这时另外一种考虑方式,而且他是不需要额外空间的,他只使用一个指针来区分小于基准和大于基准的 # pointer_less_than代表这个指针的左边全部都是小于基准的(包括自己,不包括首元素) # 然后从左往右扫描,遇到小于基准...原创 2018-12-20 17:02:44 · 701 阅读 · 0 评论 -
树形结构:递归转化为迭代,万能通用方法,分治策略基于栈的实现
前面提到树的3中遍历迭代实现的时候,讲到:还有一种思路,直接针对递归的实现方式,想办法通过栈来实现递归,得到的还是和上面一样一般的递归改成迭代的方法,你需要知道迭代指针是如何走的,还要借助数据结构才能实现,就是你需要注意那些需要先放入数据结构,哪些需要后放入下面介绍的方法是一种通用方法以先根遍历为例:def preorder(root): if not root: ...原创 2018-12-20 16:43:39 · 738 阅读 · 0 评论 -
找中位数,找第k小,还存在问题
找第k小上次介绍了找第二大使用的方法时,使用锦标赛的方法,找到最大,在最大的手下败将里找第二大,也就是亚军在冠军的手下败将里产生,亚军只败给过冠军,这种方法比较次数时(n-1) + (logn-1),这个时间复杂度最优的方案了为O(n)那么怎么找第k大了,季军只能在冠军和亚军的手下败将里产生,第四名只能在前三名手下败将里产生。。。。这个方法也是O(n),但是需要记录每个选手的手下败将名单还有...原创 2018-12-14 17:15:57 · 165 阅读 · 0 评论 -
树形结构:迭代方式遍历树,宽度优先,先序遍历,中序遍历,后序遍历
迭代的方式处理树,就必须清楚你将要访问的顺序,对应的就是指针怎么走,你必须很清楚树的宽度优先搜索,他是一层一层的访问,就搞不清楚怎么划分子问题了,但是你访问的顺序你很清楚,那么就使用迭代的方式实现,你的指针应该可以按照一层一层的走怎么走?在线性结构里,我们处理的是数组,可以直接一个一个的走在树里,按照层次访问,每一层结点之间是跳跃的,那我们该怎么实现指针的连续走动?很容易的思路,把每一层...原创 2018-12-19 17:15:13 · 1538 阅读 · 0 评论 -
树形结构:二叉树,分治,合并子树,递归
我们学习树的时候,一些地方用到了递归,但是可能没意识到这里面都是分治的思想=============================================================================结合这几个例子,体会一下树形结构树本来就是一个天然的递归结构,每一个递归都对应着一个递归树就二叉树而言,每一个二叉树对应着一个左子树,一个右子树都不用我们思考怎么...原创 2018-12-19 15:34:29 · 664 阅读 · 0 评论 -
分治法:关于选择算法,找最大,找最小,同时找最大和最小,找第二大
找最大或者最小,蛮力算法为最优的算法,需要比较n-1次# 这个已经是最优的算法了,比较n-1次def findMax(arr): max_pivot = arr[0] for i in range(1,len(arr)): if arr[i] > max_pivot: max_pivot = arr[i] ...原创 2018-12-13 16:52:11 · 7228 阅读 · 0 评论 -
算法优化:动态规划加速,货物运输问题,四边形不等式, 从O(n^2)到O(n^3)
货物运输问题递归方程为:更为一般形式的递归方程看起来是不是像可以使用分治的策略实现,但是min里面子问题太多了,只能使用动态规划的招了。i,j是什么含义了?动态规划里i,j都是指的是问题规模,对应到货物运输问题指的是什么了?我们从数学上理解i,j是指数组arr = [1,2,3,4,5,6,7,8]两边的标号,或者子问题对应的起始和终止标号,类似与快排里面的数组的标号,实际问题抽象为...原创 2018-12-17 13:59:38 · 1398 阅读 · 0 评论 -
树形结构:寻找共同祖先
寻找共同祖先输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1输出: 3解释: 节点 5 和节点 1 的最近公共祖先是节点 3。首先是需要构造树class BinTNode: def __init__(self,data=None,left =None,right =None): self.data =d...原创 2018-12-22 12:01:08 · 1181 阅读 · 0 评论 -
树形结构:二叉排列树,二叉搜索树
二叉排列树,二叉搜索树这个数听见得比较多,含义是:左边<=中间<=右边,换句话来说使用中序遍历最后得到结果就是一个有序得序列。建立一颗二叉排列树class BinTNode: def __init__(self,data=None,left =None,right =None): self.data =data self.left =lef...原创 2018-12-22 14:23:07 · 182 阅读 · 0 评论 -
机器学习:结点的实现,决策树代码实现(二)
文章目录楔子定义变量:定义方法获得划分的feature生成结点停止条件及其处理fit()生成树剪枝楔子前面已经实现了各种信息量的计算,那么我们划分的基本有了,那么我们需要使用这个基本来划分,来生成决策树,树的基本单元是node,这里的node是一堆数据的集合+他们内在的方法。由于需要处理三种算法,我们最好能使用基类,该类应该至少包含:1、选择划分的feature;2、根据基准划分数据生成新...原创 2018-12-30 11:17:21 · 407 阅读 · 0 评论 -
图形结构:安排课程,图的遍历策略
安排课程,N门课程相互约束,prerequests = [[1],[2],[0]],上第0门课需要先上第1门课,上第1门课需要线上第2门课,上第2门课需要线上第0门课。在这里我们需要体会图的遍历,有时并不需要完全遍历图,遍历图是按照某种策略的,比如BFS策略是遍历离当前结点最近的未遍历的所有的点,DFS遍历当前结点最近的一个点,在图的遍历中,特别是对实际问题,明确什么是点,什么是边,以及遍历的贪...原创 2018-12-25 10:21:07 · 200 阅读 · 0 评论 -
寻找数组变化:树形结构,分治模型
寻找数组变化给定数组arr = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1],返回第一个1的下标很明显需要借助于二分查找,二分查找轻微变形就可以实现第一种思路:二分查找,把数组分成3个部分,left,mid,right,判断mid是否满足要求,是的话,直接退出,否的话处理一边,这个是完全的二分查找的思路递归实现如下:def binarySearch(...原创 2018-12-19 11:33:50 · 138 阅读 · 0 评论 -
双针模型:验证括号,特殊case处理
我们知道双针:一般形式,两个指针都从左到右扫描,或者一头一尾两边朝中间扫描,或者在两个数组里扫描验证括号,这个问题:一个指针扫描当前数组,另一个指针指向的是栈顶元素,也是双针模型的一种变形。从这里例子,我们还需要学习一下,编码完毕之后,注意检查特殊的case,让程序perfect!!代码实现如下:# -*- coding: utf-8 -*-# 用于右括号和左括号匹配def left...原创 2018-12-19 10:03:35 · 173 阅读 · 0 评论 -
图形结构:克隆图,图的遍历的应用,递归和迭代
克隆一张无向图,图中的每个节点包含一个 label (标签)和一个 neighbors (邻接点)列表 。克隆图时图的遍历的应用,树的遍历,图的遍历是最基本的操作,他们和数组的遍历是一样的,线性结构的问题都是在数组遍历的基础上进行操作,同样树的问题和图的问题也都是在其遍历的基础上操作,我们所要做的是在遍历的基础上添加数据的操作。# Definition for a undirected gra...原创 2018-12-24 11:44:13 · 255 阅读 · 0 评论 -
合并数组:双针模型,原地实现
合并数组给定两个数组a = [4,5,6,9,0,0,0]b = [1,2,3]最后输出[1, 2, 3, 4, 5, 6, 9]第一种实现方式双针模型:def sortTwoSortedArry(a,b): b_num = len(b) a_num = len(a)-b_num li = [] i ,j =0,0 # 双针模型从左往右...原创 2018-12-18 16:36:13 · 190 阅读 · 0 评论 -
kSum,实现方式,动态规划
kSum关于3Sum可以,先遍历第一个数,剩下的和求2Sum对于kSum的问题,很容易想到使用动态规划,问题规模由3个方面:元素个数n,kSum的k,以及目标target状态方程为:dp[n][k][target] = dp[n-1][k-1][target-arr[n]] (选第n个数)+ dp[n-1][k][target](不选第n个数)为可能性问题,最后必须装满,也就是k=0时,t...原创 2018-12-18 14:33:38 · 1486 阅读 · 0 评论 -
TwoSum,从O(n^2)到O(nlogn)再到O(n)
TwoSum,两数之和Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution, and you may not us...原创 2018-12-18 12:04:09 · 621 阅读 · 0 评论 -
图形结构:遍历模型,分治法,动态规划,回溯法,BFS,DFS
图形结构,是树形结构的扩展。我们在回溯法里面了解到几种结构:二叉树,排列树,完全n叉树,这几种解空间类型,都可以直接使用回溯法的框架解决。二叉树,排列树,完全n叉树,都可以看成x叉树的变形,而图形结构就是x叉树。在此之前,我们先明白一点:一颗二叉树是什么,他是某一颗二叉树的子树,同样的道理,一个图是什么,他是某个图的子图。一般的二叉树问题,我们先处理当前结点,再处理左子树和右子树,对应一般...原创 2018-12-23 12:44:12 · 1287 阅读 · 1 评论 -
分治法:归并排序
归并排序的思想:对集合的排序,可以看成他们子集合的分别排序,然后把各个有序的子集合合并成有序的全集,这里一般把原集合尽可能的均分为2个子集合。可以看出这里有两个工作量,一是把原数组不断的对半切,直到子问题足够小可以直接解出,二是把两个有序的数组合并成一个有序的数组。def MergeSort(arr,N): # 递归出口,出口需要返回当前的那个数 if N == 1: ...原创 2018-12-11 17:01:13 · 199 阅读 · 0 评论 -
动态规划,分治,回溯法,全排列,切片
全排列问题,可以从动态规划状态方程考虑,也可以从回溯法考虑,二者代码递归形式的代码是一致的,但是理解的角度不同动态规划:# 基于动态规划,状态方程考虑,f[n] = 首位为所有元素 + f[n-1],这个动态规划没有重复# 子问题,每一种情况都需要遍历class Solution2: def permute(self, nums): """ :typ...原创 2018-12-22 16:58:55 · 421 阅读 · 0 评论 -
树形结构:从二分查找,二叉搜索树寻找最近祖先,从递归到迭代,实现技巧总结
二分查找,二叉搜索树寻找最近祖先均是典型分治问题,把原问题分成三部分考虑,递归实现简单,迭代实现也比较简单,里面蕴含了一些从从递归到迭代的技巧,注意这里没有使用模拟栈技术。深究其原因是,这一类型的递归,每次查找丢弃了一半,递归到底部就找到了问题的解,搜索到最小子问题就解决了问题,类似于分支限界剪枝,剪到最后就是问题的解,不需要一层一层的回退,也就没有必要使用栈来恢复现场。二分查找,递归和迭代...原创 2018-12-22 14:55:58 · 218 阅读 · 0 评论 -
分支限界发:Dijkstra算法
从分支限界的角度来看Dijkstra算法:Dijkstra算法是基于贪心的广度优先搜索,也可以看成分支限界法,从分支限界的角度来看,Dijkstra算法看起来就更加清晰明了代码实现:# =============================================================================# 分支限界法,dijkstra算法# 首先解空间...原创 2018-12-06 13:43:34 · 1032 阅读 · 0 评论 -
限界分支法优先级队列方式出口和追踪解的两种方法总结
在优先级队列分支限界法法中,何时为出接口,也就是while循环何时退出了?解空间为[0,1,2…,n-1],当depth = n-1时,就可以记录结果了,可以考虑循环体退出了(实际上能不能出,还要看他的权够不够大,不够大的话,还是要老老实实的去选择优先级高的分支),换句话来说,一旦有一个一个叶子节点弹出了,循环体就结束了然后就是最优解和最优解方案的追踪一般来说有两种方案:在每个活结点(就是...原创 2018-12-06 11:19:28 · 210 阅读 · 0 评论 -
多重背包从简单到复杂
题目有 N 种物品和一个容量为 V 的背包。第 i 种物品最多有 M i 件可用,每件耗费的空间是 C i ,价值是 W i 。求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。状态转移方程:F [i , v] = max {F [i − 1, v − k ∗ C i ] + k ∗ W i | 0 ≤ k ≤ M i }复杂度是 O(V ΣM i ) 。...原创 2018-11-17 12:40:45 · 165 阅读 · 0 评论 -
回溯法解决01背包问题
回溯法问题的关键在于如何定义问题的解空间,转化成树(即解空间树)。只要是解可以描述成向量方式的,就可以使用回溯法,不断的扩张部分向量,向下深入的过程就是,从部分解到可行解的过程。解必须满足多米诺性质:可行解满足约束–&amp;amp;gt;部分解满足约束逆否为:部分解不满足约束–&amp;amp;gt;可行解不满足约束这样可以用来pruning。最简单的回溯,解空间为二叉树,又叫子集树递归方式实现的框架如下:v...原创 2018-11-22 17:09:33 · 4565 阅读 · 0 评论 -
Dijkstra和动态规划
有人说Dijkstra也是动态规划。它不是贪心吗?怎么变成动态规划了,是动态规划的话,那么就有状态,有状态方程。将图中的顶点分成2个部分,已知最短路径的顶点集合U,不知最短路径的集合V-U问题规模:就是U里面顶点个数状态:已知最短路径长度:状态方程如下:如果v 在 U中:cdis[v] = dis[v]如果v和U中某点u直连:cdis[v] =min(dis(u) + w(u,v))...原创 2018-11-21 16:38:12 · 5389 阅读 · 0 评论 -
Bellman-Ford 算法 和 动态规划
Floyd算法:状态:d[k][i][j]定义:“只能使用第1号到第k号点作为中间媒介时,点i到点j之间的最短路径长度。”动态转移方程:d[k][i][j] = min(d[k-1][i][j], d[k-1][i][k]+d[k-1][k][j])(k,i,j∈[1,n])Bellman-Ford 算法:状态:d[k][u]定义:从源点v出发最多经过不构成负权值回路的k条边到达终点...原创 2018-11-21 14:06:22 · 2083 阅读 · 0 评论 -
完全背包问题从简单到复杂
题目有 N 种物品和一个容量为 V 的背包,每种物品都有无限件可用。放入第 i 种物品的费用是 C i ,价值是 W i 。求解:将哪些物品装入背包,可使这些物品的耗费的费用总和不超过背包容量,且价值总和最大。第一种思路,基于投资问题模型从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取 0 件、取 1 件、取 2 件…直至取 ⌊V /C i ⌋ 件等许多种。状态方程为:F...原创 2018-11-16 12:25:52 · 524 阅读 · 0 评论 -
floyd算法和动态规划
楔子long long ago就已经知道了Floyd算法,关键代码就4行,也容易记住,上上周又看到了Floyd,都说是动态规划,所以特意去学了一圈动态规划,今天终于又回到了它状态方程:d[k][i][j]定义:“只能使用第1号到第k号点作为中间媒介时,点i到点j之间的最短路径长度。”在动态规划算法中,处于首要位置、且也是核心理念之一的就是状态的定义这个大家喜欢把它叫做“松弛操作”,也就是...原创 2018-11-20 16:52:15 · 1074 阅读 · 0 评论 -
动态规划,从例子到理解
如何设计动态规划?1、问题建模:得到优化的目标函数,约束条件?2、划分子问题:明确问题的规模在哪里?哪些维度的规模,这样才能才会划分子问题,注意边界。3、得到递推方程:可以宏观的考虑,也可以借助于微观的归纳演绎。4、然后检测是否满足最优子结构:检查子问题对其子问题的始、终点也是最优的序列。5、最小问题的界定,确定初值。如何编码动态规划?一般得到了递推方程,就可以写出基于递归的代码实...原创 2018-11-12 16:27:52 · 351 阅读 · 0 评论 -
01背包问题从简单到复杂
题目:有 N 件物品和一个容量为 V 的背包。放入第 i 件物品耗费的费用是 C i 1 ,得到的价值是 W i 。求解将哪些物品装入背包可使价值总和最大。状态转移方程:F [i, v] = max {F [i − 1, v], F [i − 1, v − C i ] + W i }基于递归的实现:def pack_0_1_Rec(N,V,C,W): if N == 0 or ...原创 2018-11-15 17:13:36 · 274 阅读 · 0 评论 -
Kruskal实现最小生成树
Kruskal实现最小生成树算法原理:一群孤立的顶点,在不形成环的情况下不断把最小的边连接起来。如何描述不形成环?1、书上的描述,把连接的顶点,标记为同一个连通分量,线段的起点ViV_iVi和VjV_jVj属于不同的连通分量即可,实现比较简单,只要一个标记数组就可以实现。代码实现:def kruskal2(graph): vnum = len(graph) pque...原创 2018-11-08 11:44:50 · 160 阅读 · 0 评论 -
Prim和Dijkstra居然写起来一模一样
一句话概括Prim和Dijkstra:Dijkstra:依次找距离起点从近到远的点;Prim:从起点开始找距离最近的点,且不形成环。这样表述还看不出来什么我们先对比二者的代码:def dijkstra2(graph,start): vnum = len(graph) pqueue = [] heapq.heappush(pqueue,(0.0,None,start...原创 2018-11-07 18:02:06 · 863 阅读 · 0 评论