
数据结构与算法
kkkkkkkkkrys
https://krysliang.xyz/
展开
-
leetcode刷题日记-2022-3-14
1、有效的括号https://leetcode-cn.com/problems/valid-parentheses给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。/** * @param {string} s * @return {boolean} */var isValid = function(s) { let map = { .原创 2022-03-21 15:09:42 · 349 阅读 · 0 评论 -
算法日记-跳表
/** * * 跳表: * * 普通的单链表,一个节点指向下一个节点,如果想要在单链表中查找一个元素,必须要遍历整个链表才可以搜索到这个元素。 * 那么,如果我们想要像二分查找那样对链表进行搜索查找呢? * * 此时我们可以用另一个链表简历索引,每两个元素建立一个索引。比如 * * 1->2->3->4->5->6->7->8->9->10 * * 如果要查找的元素是10,那么我们就要从1开始遍历链表,查找到10则需要遍.原创 2022-03-14 17:19:19 · 198 阅读 · 0 评论 -
JavaScript B+树
/** * B+树的构造 * * * 1、第一步 改造二叉查找树(左边的子节点比当前节点小,右边的子节点比当前节点大) * 树中的节点并不存储数据本身,而是只作为索引,然后再每个叶子节点串在一条链表上,链表中 * 的数据是从小到大有序的。 * 改造以后,只要拿着区间的起始值在树中进行查找,当查找到某个叶子节点的时候,顺着链表往后遍历, * 直到链表中的结点数据值大于区间的终点值。那么遍历到的数据,就是符合区间值的所有数据。 * * 2、第二步 降低树的高度 减少读取节点的操作 从.原创 2022-02-09 11:43:16 · 1194 阅读 · 1 评论 -
JavaScript中跳表的定义与实现
调表原创 2022-01-24 16:04:29 · 442 阅读 · 0 评论 -
JavaScript Dijkstra算法 Astart算法
/** * 最短路径 * Dijkstra算法 * 首先根据起始顶点到当前顶点的dist 构建小顶堆,然后区堆顶元素。 * 取堆顶元素以后,需要从下往上堆化 * 然后取堆顶元素对应的邻接表中,更新每个顶点的dist值,并且入队。 */ class Graph{ constructor(v){ this.v = v;//图中的顶点 this.n = v.length; this.adj = new Array(this.n);//图...原创 2022-01-05 17:28:09 · 653 阅读 · 1 评论 -
JavaScript拓扑排序的实现
/** * 拓扑排序 * 凡是需要通过局部顺序来推到全局顺序的,使用拓扑排序来解决。 * 还可以使用拓扑排序来检测图中环的存在。 * * * 假设几个源文件之间两两之间的依赖关系已知,如何确定一个全局的编译的顺序呢? * 比如a依赖b,b依赖c,d依赖b * 那么编译顺序就是 c->b->a->d * 或者c->b->d->a * * * 我们使用一个有向无环图来实现拓扑排序。 * 文件之间的依赖关系抽象成一个有向图,每个源文件就是一个.原创 2022-01-05 17:27:00 · 1103 阅读 · 2 评论 -
JavaScript动态规划的实现
/** * 动态规划 * 一个模型 三个特征 * 一个模型:动态规划适合解决的问题的模型:“多阶段决策最优解模型” * 三个特征:1、最优子结构(可以通过问题的子问题的最优解推导出问题的最优解)、无后效性、重复子问题 * 解决动态规划的两种思路:1、状态转移表法和状态转移方程 * 1、状态转移表:拿到问题的时候,定义状态,每个状态代表一个节点,然后画出递归树,从递归树中就可以看出来, * 是否存在重复子问题。然后画出一个状态表,每个状态包含三个变量,行、列、数组值。 * 根据决策的先后过程.原创 2021-12-24 15:24:18 · 243 阅读 · 0 评论 -
JavaScript贪心算法
/** * 贪心算法 * 贪心算法有:霍夫曼编码、prim和kruskal最小生成树算法、Dijkstra最短路径算法。 * * 什么是贪心算法: * * 1、针对一组数据,问题有限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期望值最大。 * 2、每次选择当前情况下,在对限制值同等贡献量的情况下,对期望值贡献最大的数据。 * 3、举几个例子看下贪心算法产生的结果是否是最优的。 * * * 举例子 * 1、区间覆盖 * 假设有n个区间,区间的起始断点和结束断点.原创 2021-12-24 10:12:28 · 783 阅读 · 1 评论 -
算法-分治算法
分治算法原创 2021-12-24 10:11:42 · 109 阅读 · 0 评论 -
算法-回溯
回溯原创 2021-12-24 10:10:42 · 486 阅读 · 0 评论 -
算法-字符串匹配
字符串匹配原创 2021-12-07 15:39:13 · 209 阅读 · 0 评论 -
图 图的广度优先搜索、深度优先搜索
图、图的深度优先、广度优先原创 2021-11-23 17:43:27 · 329 阅读 · 0 评论 -
堆(优先队列)
堆(优先队列)原创 2021-11-22 14:48:44 · 114 阅读 · 0 评论 -
树与二叉树
/***树*树的概念**节点的高度=节点到叶子节点的最长路径(边数)*节点的深度=根节点到节点的路径(边的个数)*节点的层数=节点的深度+1*树的高度=根节点的高度(根节点到叶节点的个数)*//***二叉树*二叉树的概念*二叉树,每个节点最多有两个子节点,分别是左子节点和右子节点。**当除叶节点以外所有的节点都拥有左右子节点,且叶节点都在最底层的树,叫满二叉树。*...原创 2021-11-16 14:35:56 · 1151 阅读 · 0 评论 -
JavaScript哈希表
/** * 哈希表(散列表) * * 散列的思想,就是用key对应着一个value。将key转换为value的方法叫做散列函数,而散列函数得到的value就是散列值, * 散列值也叫做哈希值。这个value就对应着数组的下表,然后根据value去数组中对应的位置存取数据。 * * 散列函数,hash(key),其中key表示着元素的键值,has(key)-》value就是经过散列函数计算得到的散列值(哈希值)。 * * 散列函数设计的基本要求 * a.散列函数计算得到的散列值...原创 2021-11-10 14:02:47 · 1286 阅读 · 1 评论 -
JavaScript二分查找
/** * 二分查找法 * * 二分查找针对的是一个有序的数据集合,查找思想有点类似于分治思想。 * 每次都通过跟区间的中间元素对比,待查找的区间缩小为之前的一半,等找到要查找到的元素,或者区间被缩小为0. * 时间复杂度为O(logn),非常高效的时间复杂度。 * * * * 二分查找的局限性 * 1)只能依赖于数组的这种数据结构,因为二分查找依赖于随机访问下标。 * 2)只能依赖于有序的数组。如果数据还没排序过,需要先排序再进行二分查找 * 3)只能使用与一组静态的数.原创 2021-11-02 17:09:34 · 127 阅读 · 0 评论 -
剑指offer day 3
1、剑指 Offer 05. 替换空格var replaceSpace = function(s) { let newS = s.split(' '); return newS.join('%20')};2、剑指 Offer 58 - II. 左旋转字符串var reverseLeftWords = function(s, n) { let s1 = s.slice(0,n); let s2 = s.slice(n,n.length); r.原创 2021-10-21 14:05:40 · 167 阅读 · 0 评论 -
刷题日记3
1、剑指 Offer 06. 从尾到头打印链表/** * @param {ListNode} head * @return {number[]} */var reversePrint = function(head) { let stack = [],cur = head; while(cur){ stack.unshift(cur.val); if(cur){cur = cur.next;} } return stack;}原创 2021-10-20 15:52:56 · 77 阅读 · 0 评论 -
刷题日记-剑指 Offer 30. 包含min函数的栈
题目地址剑指 Offer 30. 包含min函数的栈解题思路:一个栈存放原来正常的数据,一个栈存放每次入栈时当前栈中最小值。var MinStack = function() { this.stack = [];//原来的栈 this.ministack = [Infinity]//存放按照压栈顺序中最小的那个值};/** * @param {number} x * @return {void} */MinStack.prototype.push = funct原创 2021-10-19 17:30:30 · 127 阅读 · 0 评论 -
算法刷题日记-剑指 Offer 09. 用两个栈实现队列
题目地址力扣解题思路:有两个数组,一个作为入栈数组,一个作为出栈数组。入栈直接将元素压栈;出栈的话,如果出栈数组还有元素就直接出栈,否则将入栈数组的元素全部出栈压到出栈数组中。var CQueue = function() { this.stackA = []; this.stackB = [];};/** * @param {number} value * @return {void} */CQueue.prototype.appendTail = fun原创 2021-10-19 16:53:56 · 98 阅读 · 0 评论 -
算法刷题笔记-两数相加
/** * @param {ListNode} l1 * @param {ListNode} l2 * @return {ListNode} */var addTwoNumbers = function(l1, l2) { let head = new ListNode(-1); let cur = head; let sum = 0,inter = 0; while(l1 || l2){ let val1 = l1?l1.val:0; .原创 2021-10-19 16:26:55 · 95 阅读 · 0 评论 -
算法刷题笔记-数字的补数
这题有两个思路:第一个就是暴力法,遍历每位进行判断赋值,结合js的方法varfindComplement=function(num){letbinString=num.toString(2)letnewString=''for(leti=0;i<binString.length;i++){if(binString[i]=='0'){new...原创 2021-10-18 17:22:41 · 79 阅读 · 0 评论 -
几个常用的排序算法
一、插入排序插入排序分为直接插入排序和折半插入排序1、直接插入排序首先我们将数组的数据分为两个部分,已排序区间和未排序区间(在同一个数组中)。初始已排序区间只有一个元素,就是数组的第一个元素。算法的核心思想是取未排序区间中的元素,在已经排序区间中找到合适的插入位置将iq插入,并保证已排序区间数据一直有序。重复这个过程直到未排序区间中元素未空。当我们需要将一个数据a插入到已排序...原创 2019-11-28 18:02:43 · 169 阅读 · 0 评论 -
栈与队列
一、栈栈是一种“操作受限的线性表”1、栈主要包含两个操作,入栈和出栈,也就是在栈顶插入一个数据,在栈顶删除一个数据,也就是说所有的操作都是在栈顶进行的。2、用代码实现一个栈栈的实现有两种,如果是用数组实现的叫做顺序栈,如果是用链表实现的叫链式栈。下面来用js实现一个顺序栈class Stack{constructor(){thi...原创 2019-11-28 10:49:11 · 209 阅读 · 0 评论 -
复杂度分析
复杂度分析(一)如何分析、统计算法的执行效率和资源消耗1、大O复杂度表示法算法的执行效率,粗略的讲,就是算法代码执行的时间。所有代码执行的时间T(n)与每行代码的执行次数n成正比。这个规律总结成一个公式就是大O了T(n) = O(f(n)这条公式里,Tn代表的是代码执行的时间,n代表的是数据规模的大小,fn表示每行代码执行的次数总和。公式中的O代表的是代码时间与...原创 2019-11-26 11:20:45 · 1486 阅读 · 0 评论 -
数组与链表
数组一、基本概念1、什么数组?数组是一种线性表的数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。2、数组是如何实现下标随机访问数组元素的?我们拿一个长度为10的数组来举例,在下面的图中,计算机给数组分配了一块连续的内存空间,其中内存的首地址为base_address=1000。每次获取数据的时候,计算机都会根据下面的寻址公式计算出元素的存储的内存...原创 2019-11-26 11:17:09 · 464 阅读 · 0 评论