数据结构与算法
K3v
这个作者很懒,什么都没留下…
展开
-
合并两个有序数组
【代码】合并两个有序数组。原创 2024-05-04 17:28:49 · 118 阅读 · 0 评论 -
【ds】替换空格
用‘%20’替换空格。原创 2024-04-20 17:07:10 · 110 阅读 · 0 评论 -
【ds】二维数组中的查找
请 完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。在一个二维数组array中(每个一维数组的长度相同)每一列都按照 从上到下递增的顺序排序。每一行都按照 从左到右递增的顺序排序。原创 2024-04-20 15:22:51 · 76 阅读 · 0 评论 -
148. sort list 排序链表
148题排序链表题目要求:O(n log n) 时间复杂度和常数级空间复杂度下方法 1, 暴力法,取出来放数组里面,排序,然后重新生成链表,但是不符合题目的要求 2,递归 【自上而下】 思路就是: 2-1,找到链表的中间点(参考找到链表中间点) 2-2,对 中间点分割成为的两个链表分别进行排序,到这里就是调用自己了,递归,对两个链表进行排序。 2-3, 然后合并这两个 有序链表(参考合并有序数组) 3,迭代 【自下而原创 2021-03-07 16:32:48 · 371 阅读 · 0 评论 -
876. Middle of the Linked List 利用快慢指针求链表的中间节点
比如链表结构为1->2->3->4->5 此时中间节点为 3如果链表结构为 1->2->3->4 此时中间节点为2或者3节点定义利用golang来描述这个实现过程,ListNode的节点实现type ListNode struct { Val int Next *ListNode}实现func middleNode(head *ListNode) *ListNode { slow := head fast := head // 循环遍历完原创 2021-02-19 21:47:47 · 150 阅读 · 0 评论 -
给定一个数组,正序遍历和逆序遍历构造一个链表
链表基础 单链表的数据定义为: function ListNode(val) { this.val = val; this.next = null; } 需求:给定一个数组 比如 [ 2, 5, 9, 10] 构造一个单链表,结果为2 -> 5 -> 9 -> 10, 但是需要以两种方式去做, 正序遍历构造: function constructLinkedList(arr) { let dummy = new List原创 2021-01-24 17:43:10 · 213 阅读 · 0 评论 -
求最大公约数
迭代版本 function getCd(a, b) { if (a * b < 0) return 1 if (a ==0 || b == 0) return 0 while( a % b != 0 ){ var c = a % b; a = b; b = c; } return b }递归版本 function getCd(a, b) { if (a == 0 || b == 0) return 0原创 2021-01-09 17:36:44 · 1154 阅读 · 0 评论 -
寻找有序数组中元素第一次出现的索引和最后一次出现的索引
有序数组 比如 [1,2,3,4,4,4] 这个在js里面可以直接使用findIndex与lastIndexOf来求出,如果我们自己用代码实现该如何做呢? 看到有序数组的查找,没错,二分 二分,对于有序的数据,总能用二分去解决。findIndex的实现代码:var findFirstIndex = (arr, target) => { let l = 0 let r = arr.length - 1 while(l <= r) { let mid = Ma原创 2020-12-12 23:59:20 · 2069 阅读 · 0 评论 -
【排序】计数排序
为什么记录这个在做 leetcode 561 题的时候,第三种解法,看了很久才明白,是做了一次计数排序。这个题,直接看第二种和第三种解法。 第二种的排序时间复杂度是O(nlogn) 第三种的排序时间复杂度是O(n)直接看计数排序代码:var countSort = (nums) => { // 这里arr的长度没有设定,利用了javascript的语言特性 // 其他语言,这里的长度应该要保证 arr[Math.max(...nums)]不会越界 let arr原创 2020-11-21 16:13:22 · 130 阅读 · 1 评论 -
【排序】归并排序
归并排序 归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作. 参考之前的,合并两个有序数组这里我们合并两个有序数组。可以做到排序操作,但是前提是两个有序序列。 对一个杂乱无序的序列,我们可以递归的将两个子序列排列成有序的序列, 子序列可以通过二分法再次划分为两个子序列,直到最后两个子序列只有一个数据。 分治法的应用。实现 /** * 归并排序 - 递归方式实现 */ var sort = (arr) => {原创 2020-10-11 15:39:22 · 141 阅读 · 0 评论 -
【排序】快速排序
快速排序 快速排序和冒泡排序都是是交换排序中的一种。基本思想 1,在数列中找准一个基准点pivot。 2,将比基准点小的所有值放在基准点的左边,将比基准点大的放在基准点的右边【相等的可以任意放置】。 3,对左边的子数列和右边的子数列,重复1到3的步骤。分而治之,是的递归来了。代码 var sort = (arr, low, high) => { if (!arr || arr.length === 1) return arr // 重要的边界条件原创 2020-10-10 14:37:29 · 110 阅读 · 0 评论 -
【排序】冒泡排序
冒泡排序(英语:Bubble Sort)又称为泡式排序,是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。假定数组为arr,长度为n第1个元素开始,比较n-1次,第1次走完,最大(or最小)已经在最后一个位置上。第2个元素开始,比较n-2次,第2次走完,第二大(or第二小)在倒数第二个位置上。…第n-1个元素开始,比较1次。第n个元素,不需要比较。代码长这样:var原创 2020-10-10 13:07:15 · 212 阅读 · 0 评论 -
插入排序-简单插入排序和二分插入排序
插入排序:插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。基本思想每一步都是将 待排序的一个数据,插入到一个已经有序的数据序列里面。直到所有的数据全部插入为止。类似于打牌【斗地主】,每摸一张就按照顺序放到位置。每原创 2020-10-08 15:06:07 · 342 阅读 · 0 评论 -
数据结构与算法-平衡二叉树【二十】
前景提要因为线性表(假定长度为n)在动态的添加和删除的弊端,所以我们引入了二叉搜索树,但是二叉搜索树有多种形式最好的情况是 线性表的 判定树最坏的情况是这颗二叉搜索树的深度为n,每一层一个节点。最好的情况是这样:ASL = log2(n + 1) - 1 数量级为O(log2n) 5 第一层 / \原创 2020-09-24 21:40:05 · 354 阅读 · 0 评论 -
数据结构与算法-BST二叉搜索树(二叉排序树)【十九】
线性表在添加和删除的效率较低,所以我们考虑特殊的树,考虑这种存储结构,提高查找效率,以及动态添加和删除的效率。这时会引入 【二叉搜索树】二叉搜索树的定义定义【仍然是递归定义】:左子树为空,那么左子树上的所有值一定是小于根节点的值。右子树不为空,那么右子树上的所有值一定是大于等于根节点的值。左右子树也是一颗二叉搜索树。二叉搜索树 也称为二叉排序树例子: 5 第一层 /原创 2020-09-13 18:00:44 · 511 阅读 · 0 评论 -
数据结构与算法-线性表的查找【十八】
查找:在特定的数据集合中,找到复合要求的数据。查找的效率判断:结构里面有一个专门的词汇,平均查找长度。通过这个关键指标去判断。平均查找长度关键字的平均比较次数,也称为平均查找长度。查找到关键字的平均比较次数。【很明显这个值越小查找效率越高】n 为总记录的个数;pi 查找到第i个记录的概率(通常pi就是1/n);ci 找到第i个记录需要比较的次数;线性表的查找线性表的查找有三种方式:顺序查找折半查找(二分查找)分块查找下面分别介绍1,顺序查找 线.原创 2020-09-10 22:06:28 · 1851 阅读 · 0 评论 -
数据结构与算法-最小生成树【十七】
生成树:所有的点由边连接在一起,但是【不存在回路】的图。生成树的特点:树是 图的 极小连通子图, 去掉一条边,则非连通。在生成树中再加一条边必然形成回路。生成树中任意两点之间的路径是唯一的。一个有n个顶点的连通图的生成树有n-1条边。...原创 2020-08-30 17:00:57 · 714 阅读 · 0 评论 -
数据结构与算法-图的广度优先遍历【十六】
图的广度优先遍历与树的广度优先遍历类似,用队列来实现。节点出队,节点的所有邻接点入队。如此循环,直到队列为空。还是以邻接矩阵表示图,咱们用下面这个图。用邻接矩阵去表示这个图,邻接表的广度优先遍历思路是一致的,只是去找邻接点的时候邻接表会更快。图的定义: function Graph(vexs = [], arcs = []) { this.vexs = vexs this.arcs = arcs }vexs 存储了4个顶点:const vexs= [原创 2020-08-16 15:38:11 · 1528 阅读 · 0 评论 -
数据结构与算法-图的深度优先遍历【十六】
对于图的遍历,也分为深度优先遍历与广度优先遍历。深度优先遍历:一条路走到黑,直到没有遍历过过的节点,那么回退,不然一直往下面走。还是以之前的这个邻接矩阵为例:以这个邻接矩阵为例:图的定义: function Graph(vexs = [], arcs = []) { this.vexs = vexs this.arcs = arcs }vexs 存储了4个顶点:const vexs= [ 'A', 'B', 'C', 'D']arcs是一个二维数组原创 2020-08-16 15:24:25 · 1078 阅读 · 0 评论 -
数据结构与算法-根据给定的的路径还原一棵树
这一组路径肯定是以rootNode为起点,但是不一定以叶子 节点结束,给的示例数据如下,a是b的父亲节点,a是e的父亲节点,以此类推arr[i+1]的元素是arr[i]的孩子: const arr = [ ["a", "b"], ["a", "e"], ["a", "f"], ["a", "i"], ["a", "i", "j"], ];代码: // 已知所有的路径求一颗完整的树function getTreeByPaths(arr) { //原创 2020-08-15 15:49:42 · 881 阅读 · 0 评论 -
数据结构与算法-图论 邻接表【十五】
链式存储 (链式表示) 上一话说的是邻接矩阵方式去存储图,这一话用链表去存储图链式表表示法----【邻接表/ 邻接多重表 / 十字链表】邻接表 将所有的顶点数据仍然存放在一维数组内。 这个一维数组比较特殊,顶点数组的每个元素都指向一个邻接点单链表。咱们以上一个邻接矩阵用到的一个有向图和无向图为例:无向图 的邻接表第一个无向图的邻接表可以这样表示:A邻接于B->C->NULLB邻接于A ->C ->原创 2020-08-02 17:23:42 · 5892 阅读 · 0 评论 -
数据结构与算法-图论 邻接矩阵【十四】
图的定义数据之间的关系可能是多种的,逻辑结构上来讲,分几种:线性结构非线性结构 【包括三种: 集合结构,树形结构,图状结构】线性结构线性结构的几种表现方式,前面大部分都了解过了:线性表 (List)栈(特殊的线性表) 【先进后出】 (Stack)队列(特殊的线性表)【先进先出】 (Queue)字符串,数组,广义表【广义表是特殊的线性表,广义表的元素可以是子表,子表的元素也可以是子表;如果广义表的每个元素都是原子,它就变成了线性表】非线性结构非线性结构中的 树(clic原创 2020-08-01 14:53:41 · 3455 阅读 · 0 评论 -
数据结构与算法-哈夫曼编码【十三】
定义 哈夫曼树: 带权路径长度和最短的二叉树,也称之为最优二叉树。 哈夫曼编码:在网络传输过程中,对所有的信息进行编码,所有的信息都将转换为0101的二进制形式,根据信息出现的频率,将信息构造成长度最短的编码。原理 比如字符ABCDEBAADF 的字符集合。传输过程中,我们将每一个字符转换成二进制的形式,但是同时要保证这个二进制数据的长度最小。【保证传输的效率】 这就可以和哈夫曼树联系起来,出现概率最大的字符离根节点最近,出现概率最小的字符离根节点最远;原创 2020-07-13 21:31:12 · 353 阅读 · 0 评论 -
数据结构与算法-构造哈弗曼树【十二】
哈弗曼树的定义哈佛曼树的定义: 带权路径长度最短的树。每一个叶子节点有一个权重值,权重值 乘以 路径长度【路径长度指的是根节点到该节点的路径长度】 ,所有叶子节点的 带权路径长度 之和最小的树,称之为哈弗曼树,也称之为最优二叉树。n为所有叶子节点的个数,w为该叶子节点的权重,length©为该叶子节点的路径长度,改图来自于维基百科。...原创 2020-07-04 21:22:08 · 640 阅读 · 0 评论 -
数据结构与算法-树与二叉树的相互转换【十一】
一个普通的树可以转换成一个唯一的二叉树,原则就是:左孩子 右兄弟。一个节点的左子树的根节点,是这个节点的孩子节点的第一个,这个节点的右子树的根节点,是这个左子树的根节点的兄弟节点。普通的树转化为二叉树二叉树的节点定义: // 二叉树的节点定义function TreeNode(val, left, right) { this.val = (val===undefined ? 0 : val) this.left = (left===undefined ? null : left) th原创 2020-06-27 15:00:25 · 1574 阅读 · 0 评论 -
数据结构与算法-根据后序遍历和中序遍历的结果构建二叉树【十】
在这里已经确定了思路:1,根据后序遍历,确认根节点;2,确认了根节点之后,在中序遍历里面,确认左子树和右子树;3,根据后续遍历,确认下一个根节点;4,根据这个跟节点在中序遍历中的位置,确认这个根节点的左子树和右子树;……重复……树节点的定义: function TreeNode(val, left, right) { this.val = (val===undefined ? 0 : val) this.left = (left===undefined ? n原创 2020-06-07 14:14:01 · 1646 阅读 · 1 评论 -
数据结构与算法-求二叉树的最大深度,总节点个数,叶子节点个数【九】
标签(空格分隔): 二叉树深度 节点对应着leetcode的题目编号是: 104,222思路一这3个问题,最简单的办法就是定一个全局变量,然后遍历整棵树,最后对全局变量进行处理或者返回即可。【可以理解为自上而下,从根节点开始往下面走】求二叉树最大深度: var maxDepth = (root) => { if (!root) return 0 const arr = [] // 遍历所有,直到叶子节点 var helpFunc = (node, i原创 2020-05-24 12:49:18 · 4434 阅读 · 0 评论 -
数据结构与算法-复制二叉树【八】
Node节点的定义 /** * Definition for a binary tree node.*/ function TreeNode(val) { this.val = val; this.left = this.right = null; } 模拟先序遍历,一个一个复制, 从根节点开始错误版本: // 错误,js里面不存在传递地址引用 var copyBinaryTree = (node, newTree = null) => {原创 2020-05-23 15:24:01 · 612 阅读 · 0 评论 -
数据结构与算法-递归与非递归方式实现 先序-中序-后序遍历二叉树【八】
标签(空格分隔): 先序遍历 后序遍历 中序遍历 深度优先遍历 递归 非递归上一篇文章已经说过了,遍历树(二叉树是树的一种特殊情况)有深度优先遍历和宽度优先遍历。###深度优先遍历深度优先遍历 根据访问每个根节点与 左子树/右子树的顺序 分为 先序,中序,后序。深度优先遍历有递归和非递归的形式。二叉树的节点定义长这样: /** * Definition for a binary tree node.*/ function TreeNode(val) { this.val原创 2020-05-17 15:11:41 · 515 阅读 · 0 评论 -
数据结构与算法-遍历树,先序(或后序)与中序构建二叉树【七】
构建二叉树原创 2020-04-19 16:15:58 · 678 阅读 · 1 评论 -
数据结构与算法-树的定义【七】
标签(空格分隔): 数据结构与算法树的定义栈和队列的数据元素之间的关系从逻辑结构上来看是线性结构,就是一一对应关系。而树型结构的逻辑结构就不是一对一了,是一对多。这个链接里面介绍了,线性结构。现在讨论的树就是非线性结构中的一种【树形结构】。参考线性表的特性,线性表里面的元素,只能最多只能有一个前驱节点和一个后继节点。但是树形结构里面的元素,至多一个前驱节点,但是可以有多个后继节点。树是...原创 2020-04-19 14:09:50 · 299 阅读 · 0 评论 -
数据结构与算法-知道树的某几个叶子节点,将所有包含该叶子节点的路径组成一颗新的树
上一次记录博客是过年之前,太久了。。2月比较懒散,3月忙着加班,今天终于有时间重新开始记录点零碎的东西。前景提要,有一个特殊的需求:现在的情况是,知道叶子节点【唯一标识】以及树, 求一颗新的树。思路:递归给每一个节点一个标记。对于每一个叶子节点来说,如果已知的叶子节点包含这个叶子节点,那么给标记为true。对于非叶子节点来说,如果子节点中有一个标记为true,那么该节点标记为tr...原创 2020-04-04 16:46:13 · 1035 阅读 · 0 评论 -
数据结构与算法-字符串匹配KMP算法【六】
[数据结构与算法] 字符串的匹配算法(KMP算法)标签: 实现strStr KMP算法上一篇文章概述了一下BF算法以及缺点,这篇文章来说明一下KMP算法,对BF算法的优化。如果你还不知道BF算法是什么: 点击我 先了解匹配字符串的暴力匹配法KMP算法这个算法,是对BF算法的一个优化,为什么说优化呢,KMP算法当两个字符不相等的时候,i不需要回溯,只需要j回溯,j回溯到什么位置呢?先不看...原创 2020-01-18 16:43:55 · 507 阅读 · 0 评论 -
数据结构与算法-字符串匹配BF算法【六】
标签:BF算法 简单穷举法 实现strStr字符串的匹配算法,题目是什么呢,给定一个字符串(str) 和一个模式串(pattern)找出模式串在给定的字符串里面的位置,若不存在则返回 -1。这个对应着leetcode第28题, 当然很多高级语言都实现了这个方法,比如javascript里面,使用str.indexOf(pattern)就直接求解了,但是这个题目的要求是实现这个方法,不是调用别...原创 2020-01-18 16:25:00 · 831 阅读 · 0 评论 -
数据结构与算法-栈与队列【五】
标签:栈 队列 递归 尾递归 尾调用栈和队列都是特殊的线性表 普通的线性表,无论是以顺序存储结构表示的顺序表、链式存储结构表示的链表 可以在任意的位置【1~N+1】执行插入和删除操作。 而栈和队列,规定只能在表头和表尾部进行操作。栈是先进后出、后进先出 只能在表尾(栈顶)进行插入(入栈)和删除(出栈)。通常用Stack来表示常见使用场景: 1,括号等匹配问题 2, 函...原创 2020-01-04 15:30:15 · 165 阅读 · 0 评论 -
数据结构与算法-循环链表与双向链表【四】
我们下面讨论的前提是:1,链表有一个辅助头节点,这个辅助头结点的next才是真正的数据节点。2,单链表的定义: // Definition for singly-linked list. function ListNode(val) { this.val = val; this.next = null; }循环链表 单链表只有一个头结点 和一...原创 2019-12-21 18:05:10 · 448 阅读 · 0 评论 -
数据结构与算法-线性结构之单链表[三]
链表 线性表的存储方式除了前面讨论过的顺序存储结构【逻辑上相邻的元素在内存中存放的位置必然是相邻的】 还包括链式存储结构,逻辑上相邻的元素,映射在物理内存里面的地址并不是一定是连续的,是任意摆放的。比如 学号为 ABCDEF的6个学生: 按照 ***顺序表***来说,逻辑上他们是相邻的,我们安排他们的座位在教室里面,他们的座位一定是按照这个顺序来的,我们知道了A的位置,那么就一定知道...原创 2019-12-15 14:58:25 · 812 阅读 · 0 评论 -
数据结构与算法-线性结构之顺序表[二]
tag: 线性表数据结构:先明确一点,数据指的是什么,比如我们有一堆数字,1,2,3,4,5 这是5个数字,这一组数据5个数字是孤立的,它们是数据,但是我们给他赋予一种关系,这个关系可以是各种逻辑关系,然后就可以将这个整体【性质相同的数据集合 + 数据之间的联系】叫做数据结构。当然这个数据只要是同性质的即可,可以是整型,字符串,同一类型对象…。逻辑结构数据之间的关系可能是多种的,逻辑...原创 2019-12-08 16:08:24 · 325 阅读 · 0 评论 -
数据结构与算法-时间复杂度和空间复杂度[一]
最近在重新学习数据结构与算法。此文为笔记文。致敬: 青岛大学-王卓老师时间复杂度算法 在基础的正确性和健壮性原则上,需要考虑两个点: 1,时间效率 :算法所耗费的时间。【等待的时间是优先,肯定更要尽可能提高运算速度】 2,空间效率 :算法执行过程中所占的存储空间。【运行内存是有限的】有的情况需要结合两者一起考虑,可能需要牺牲时间节省空间,...原创 2019-11-30 16:42:53 · 566 阅读 · 0 评论 -
合并两个有序数组
var mergetTwoArrays = (nums1, nums2) =>{ var i = 0 var m = 0, lenM = nums1.length var n = 0, lenN = nums2.length var arr = [] while(m < lenM && n <...原创 2019-10-21 18:21:26 · 415 阅读 · 0 评论