![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
一日一练
每日一道算法题,锻炼早起习惯,保持思维活跃,提高编程能力
小黑地进击
这个作者很懒,什么都没留下…
展开
-
一日一练:二叉树中的最大路径和
对于这个二叉树, 要比较六个值所以和最大路径为这个时候同样需要比较六个值:从 中可以看出,之类有个重复比较过程: ,对每个子树取最大值,同时返回或者中较大值 为其父节点路径做准备。...原创 2022-06-11 16:41:50 · 59 阅读 · 0 评论 -
一日一练:二叉搜索树的最近公共祖先
因为是二叉搜索树,所以两个节点的公共祖先节点会满足: 祖先节点的值大于较小节点的值且小于较大节点的值。又因为一个节点也可以是他自己的祖先节点,所以值相等也是符合的。递归查找原创 2022-06-11 00:24:35 · 208 阅读 · 0 评论 -
一日一练:对称二叉树
思路:虚线连接的为对比的节点对这里有个技巧,根节点可以看做跟自己对比,然后再交叉比对他们的左右节点是否对称。这里用递归实现原创 2022-06-09 07:40:34 · 73 阅读 · 0 评论 -
一日一练:有效的回旋镖
这是一道数学题。如下 三点移动到原点,则移动到了,移到了,计算这两个点与轴的夹角分别为和。夹角不同,所以不在一条直接上。代码实现:向量叉乘除了,还可以用三点构成两个向量,然后根据平行的性质,叉乘为...原创 2022-06-09 00:19:03 · 200 阅读 · 0 评论 -
一日一练:爱吃香蕉的珂珂
思路:。。。原创 2022-06-08 00:28:06 · 176 阅读 · 0 评论 -
一日一练:我的日常安排I
维护一个数组,每次有新的日程安排时,先判断当前日程是否会产生重复日程:如果产生直接返回;不产生的话,加新日程加入数组中,同时返回判断方法的话:用当前日程时间与数组中维护的所有已有日程做比对:假设已有日程队列中有一个日程时间为,满足下面两点即没有交集。。。...原创 2022-06-06 23:07:55 · 61 阅读 · 0 评论 -
一日一练: 在圆内随机生成点
开始的想法是暴力求解:可能能实现,但是实现太繁琐,负责度也很高。将 圆 扩展成 正方形, 然后再矩形内确定 ,,再将不符合条件的排除出去。如上图所示,将绿松石色内的采样数据排除即可得到圆形内的数据。...原创 2022-06-05 23:26:03 · 435 阅读 · 0 评论 -
一日一练 6.4
主要在于遍历的时候给节点加上对应的层级,然后扫描的时候确保每一层的最右侧节点最后被扫描到。可以使用前序或者中序遍历。2. 相同的树从根节点开始,递归标记当前节点及其左右节点,只有节点都存在且值相同才相同。独特的电子邮件主要是字符串操作,正则的使用...原创 2022-06-04 23:00:39 · 62 阅读 · 0 评论 -
一日一练:二叉搜索树中第K小的元素
运用二叉搜索树中序遍历的特性。结果数组从小到大排列。原创 2022-06-03 23:42:56 · 115 阅读 · 0 评论 -
一日一练:合法二叉搜索树
首先得知道二叉搜索树:二叉搜索树是指一棵空树或者具有下列性质的二叉树从图和二叉搜索树定义中可以得到:二叉搜索树的中序遍历的结果是递增的数组。。。原创 2022-06-02 23:16:45 · 83 阅读 · 0 评论 -
一日一练:移除石子的最大得分
一日一练:移除石子的最大得分原创 2022-06-01 22:50:45 · 335 阅读 · 0 评论 -
一日一练:超级丑数
这道题跟丑数II的基本思路是一致的,这道题是在其基础上做了升级。中是固定的,这道题的是动态变化的。还是指针的思路,只不过这里的指针数量取决于的长度。。。原创 2022-05-31 23:02:18 · 142 阅读 · 0 评论 -
一日一练:丑数II
给你一个整数 n ,请你找出并返回第 n 个 丑数 。丑数 就是只包含质因数 2、3 和/或 5 的正整数三指针因为只包含质因数2,3,5,所以结果肯定是这些因数的乘积。这里比较难的是怎们可以让乘积可以从小到大依次被计算。这里使用三指针, 分别指向2,3,5下次相乘的数值 所在结果数组中的位置。初始化结果数组为[1],开始都是与1相乘,即都从索引0开始,所以三指针数组初始化为[0, 0, 0]2.原创 2022-05-30 23:55:09 · 60 阅读 · 0 评论 -
一日一练:积压订单中的订单总数
积压订单中的订单总数这道题在于题目的理解。这里有两种未执行的积压订单,销售订单sell 和 采购订单buy。提交订单时,如果当前订单:是采购订单,去积压的销售订单中查找价格最低的是销售订单,需要去积压的采购订单中去查找价格最高的从价格最低和最高可以确定这里可以使用堆排序。需要去销售积压订单中查找最小值,用小顶堆;需要在采购积压订单中查找最大值,用大顶堆。具体思路:判断是何种订单采购订单是否有积压销售订单没有:将采购订单加入积压采购订单有:比较采购价格是否大于销售积压订单中.原创 2022-05-30 00:03:23 · 170 阅读 · 0 评论 -
一日一练:连续中值
随机产生数字并传递给一个方法。你能否完成这个方法,在每次产生新值时,寻找当前所有值的中间值(中位数)并保存。中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。这里需要实现三个方法,构造函数 MedianFinder实例方法 addNum实例方法 findMedian主要实现的是addNum方法,如何在加入新num之后维护新的队列。排序最简单的想法是,每次加入新数据之后 都给队列排序var MedianFinder = function() { thi.原创 2022-05-28 14:51:28 · 80 阅读 · 0 评论 -
一日一练:前K个高频单词
给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。前K个高频单词,还是可以使用堆排序: 最大堆。统计单词出现的次数所有单词及数量放入堆中排序:如果出现次数不一致,用数量最比较,大的排在前面。用数量相减即可。如果出现次数一致,则用字典序排序。js中可以使用localeCompare。代码层主要是 最大堆的实现以及compa.原创 2022-05-27 23:20:20 · 114 阅读 · 0 评论 -
一日一练:设计推特
设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近 10 条推文。用map来存储每个user的tweets以及他关注的的follweeIdspostTweet方法:如果当前userId已存在map中,往tweets里再次添加,如果不存在,则初始化当前user的tweets和followeeIds。这里需要存储当前用户的postTweet的时间createTime,js这里可以用perforance.now来记.原创 2022-05-26 23:29:46 · 314 阅读 · 0 评论 -
一日一练:数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。思路:排序最容易想到的是:将数组从大到小排序,然后取第k个值。可以直接使用js提供的sort方法var findKthLargest = function(nums, k) { return nums.sort((a, b) => (b - a).原创 2022-05-25 08:45:52 · 46 阅读 · 0 评论 -
一日一练:查找和最小的K对数字
给定两个以 升序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。请找到和最小的 k 个数对 (u1,v1), (u2,v2) … (uk,vk) 。虽然这里的两个数组都是升序排列,但是两个数组的数对和的大小是不确定的,所以用暴力扫描是无法实现的。最小或者最大的K个值一般都.原创 2022-05-24 18:24:07 · 61 阅读 · 0 评论 -
一日一练:数据流中的第K大元素
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。最小堆或者排序+二分。。。原创 2022-05-23 23:18:03 · 201 阅读 · 0 评论 -
一日一练:最后一块石头的重量
有一堆石头,每块石头的重量都是正整数。每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:如果 x == y,那么两块石头都会被完全粉碎;如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。每次需要找.原创 2022-05-22 08:40:32 · 50 阅读 · 0 评论 -
一日一练:小顶堆
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。这道题的的第一种思路是sort + slice。这道题还可以使用最小堆或者说小顶堆实现。在js中并没有提供类似于Java中的工具类PriorityQueue的工具方法,这里需要自己去模拟。堆堆是一种特别的完全二叉树。二叉树可以用链表实现,也可以用数组来实现。小顶堆一般用数组来模拟。数组[1, 2, 3, 4, 5, 6, 7]:链表实现的时候,一般用node.原创 2022-05-21 16:05:59 · 323 阅读 · 0 评论 -
一日一练:平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。思路对每个节点判断器左右子树高度差是否不超过1。对一个节点,高度的计算方法:深度优先,有子节点就在总数上+1function calcHeight(root) { if (root === null) return 0 // 递归计算左节点 const leftHeight = calcHeight(root.left) .原创 2022-05-20 08:13:55 · 307 阅读 · 0 评论 -
一日一练:层序遍历
二叉树的层序遍历就是优遍历该层所有节点,然后再遍历下一层。如下图:如上图所示,二叉树:1-2-3-4-5-6-7的层序遍历顺序为1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7,结果一般用二维数组:[[1], [2, 3], [4, 5, 6, 7]]。二叉树层序遍历的整体思路:用队列维护当前层节点计算当前层的节点个数,循环(循环次数为当前数组的个数)弹出队列中的节点,收集该节点的值,同时收集他的子节点(下一层的节点)…处理下一层…直到数组中的原创 2022-05-19 22:33:39 · 308 阅读 · 1 评论 -
一日一练:N 叉树的前序遍历、翻转二叉树
1. N 叉树的前序遍历如果熟悉二叉树的前序遍历,☞ 二叉树的前序遍历。N叉树也是一样的思路。只不过将左子树和右子树的递归访问改成了对chidren的递归访问。function preorder(root: Node | null): number[] { const res: number[] = [] function dfs(node: Node | null) { if (node === null) return // 前序的收集时机 res.push(node原创 2022-05-18 08:35:11 · 109 阅读 · 0 评论 -
一日一练:二叉树的最大宽度
给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空。思路深度优先 + 递归如上图所示,按照满二叉树给每个节点标注位置:设置根节点为1,左节点为parent * 2,右节点有parent * 2 + 1那么此时可以通过每层的最右位置 - 最左位置最左位置:通过前序遍历的方式,每个level的第一个pos就是最左的位置最右位置:同层,就用 当前pos - 最左位置,每次取较大值的.原创 2022-05-18 00:06:27 · 115 阅读 · 0 评论 -
一日一练:树的子结构
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)。B是A的子结构, 即 A中有出现和B相同的结构和节点值。思路深度优先扫描二叉树A,找到值与B的根节点的值相同的节点找到之后:利用验证函数,去比对此时A的左右子节点是否与B的左右子节点的值完全相同对比过程中只要出现不相同,表明当前B不为A的子结构继续查找下一个与B的根节点的值相同的节点,继续验证是否是子结构。。。直到扫描完所以A的节点代码function isSubStructure(A, B) .原创 2022-05-16 08:35:55 · 67 阅读 · 0 评论 -
一日一练: 完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。递归:深度优先遍历对于每个节点,先去计算他的子节点的个数,直到叶子节点叶子节点的子节点数量为0,他本身以及子节点总数量为1function countNodes(root: TreeNode | null): number { if (root === null) return 0 // 递归计算子节点 // +1 是将当前节点加入计数 return countNodes(root..原创 2022-05-15 09:03:18 · 107 阅读 · 0 评论 -
一日一练:从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的前序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。☞ 首先要知道前中序遍历是什么?如果一个二叉树只有3个节点,根节点1,左节点2,右节点3,那么先收集根节点的结果,然后处理左子节点的结果,再右子节点,即[1, 2, 3],此时的遍历为前序遍历,优先遍历根节点。如果是中序遍历,就是先左节点然后根节点,最后右节点,即[2, 1, 3],优先处理左节点。☞ 思路知道前序数遍历和中序遍.原创 2022-05-14 08:54:50 · 53 阅读 · 0 评论 -
一日一练:第k个语法字符
我们构建了一个包含 n 行( 索引从 1 开始 )的表。首先在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。例如,对于 n = 3 ,第 1 行是 0 ,第 2 行是 01 ,第3行是 0110 。给定行数 n 和序数 k,返回第 n 行中第 k 个字符。( k 从索引 1 开始)思路从上图可以看出,下层中的值是由上层的0或者1生成的。具体在下层中的值是0还是1由两个因素决定:上层是0还是1下层的位置的奇偶性上层是0位置为奇数:下层值为: 0位置.原创 2022-05-13 07:55:00 · 255 阅读 · 0 评论 -
一日一练:分隔链表
给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。思路获取链表总长度count用count与k计算出每组需要放入的节点的平均数量,但是因为有可能有多余节点,所以前部分的数量可能比后面的数量多1。比如链表长度为10,分隔数量为3,每个组至少3个节点,但是因为多余1个,所以第一组的总数量为4个,要比其他组多1个从链表头节点开始将链表分组,分组数量按2中得到的组数量分隔。这里需要注意的是,.原创 2022-05-12 07:29:16 · 131 阅读 · 0 评论 -
一日一练:设计链表
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。var MyLinkedList = function () { this.len = 0 this.dummy = new ListNode(-1, null)}function ListNode(val,.原创 2022-05-11 21:28:09 · 44 阅读 · 0 评论 -
一日一练: 重排链表
给定一个单链表 L 的头节点 head ,单链表 L 表示为:L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为:L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。解题思路找中间节点快慢指针总长度 / 2翻转后半部分的链表前半部分与后半部分逐一拼接如下:代码:function reorderList(head: ListNode | null): void { .原创 2022-05-10 07:57:08 · 114 阅读 · 0 评论 -
一日一练:两数相加II
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。你可以假设除了数字 0 之外,这两个数字都不会以零开头。解题思路:翻转链表 + 逐位相加将两个链表反转从头开始每个节点依次相加,当和大于10时,要保存进位到一下次的相加;创建新节点来保存和,同时与上一次的和节点相连接当两个节点都为null时,要查看当前进位是否为0,不为0的话,继续创建节点。防止1 + 9这种情况的首位没有被计入结果。反转结果链表var add.原创 2022-05-09 08:26:29 · 33 阅读 · 0 评论 -
数据类型:单调栈
栈栈是一种抽象的数据类型,只准许在数据类型的一端加入或者移除数据(Last In First Out 后进先出)。在javascript世界中,一般用数组去模拟或者实现栈。单调栈栈中的数据有着特定的单调顺序:单调递增栈:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-okVxNFUo-1651999183106)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4d6f5623c78f4bdebe1dcd37d1原创 2022-05-08 16:41:55 · 275 阅读 · 0 评论 -
一日一题: 返回倒数第 k 个节点
实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。1. 第一种思路:计算总长度很容易想到,先扫描一遍求出链表的总长度,然后算出正向的位置,再用一次遍历完成节点的定位。function kthToLast1(head: ListNode | null, k: number): number { let count = 0 let cur = head while(cur) { count++ cur = cur.next } let posi.原创 2022-05-07 22:37:09 · 188 阅读 · 0 评论 -
一日一练:函数的独占时间
636.给你一个由日志组成的列表 logs ,其中 logs[i] 表示第 i 条日志消息,函数的 独占时间 定义是在这个函数在程序所有函数调用中执行时间的总和,调用其他函数花费的时间不算该函数的独占时间。这道题需要缓存当前正在执行的函数,用到栈。维护一个调用栈,在调用其他函数或者当前函数调用结束时更新栈。遇到start时,将函数入栈,表明调用开始;在遇到end时,需要将栈顶函数弹出,表明调用结束。以 ["0:start:0","0:start:2","0:end:5","1:.原创 2022-05-06 09:14:33 · 92 阅读 · 0 评论 -
一日一练: 基本计算器II
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。这道题还是栈的使用。思路:遇到 +、 -、 *、 /,先缓存这些运算符如果不是运算符,则收集字符串根据当前的运算符以及数字+:将字符串转成数字压入栈中-:将字符串转成数字,并取负,压入栈中*:将栈顶元素弹出,与当前字符做乘法,结果再入栈/:将栈顶元素弹出如果栈顶元素为负数,取正与字符做除法之后再去负,压入栈中如果栈顶元素为正数,直接与字符做除法,结果入栈.原创 2022-05-05 07:26:09 · 1614 阅读 · 0 评论 -
一日一练: 验证二叉树的前序序列化
序列化二叉树的一种方法是使用 前序遍历。给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。栈在解决字符串的配对问题上有奇效。比如移除无效的括号,栈匹配等等。。。如果把节点及左右节点当成一组,也可以用类似的匹配思路去解决。以 9,3,4,#,#,1,#,#,2,#,6,#,#为例首先考虑字符9,他肯定有左右两个节点,所以先将表示他数量的2入栈下一个字符,,只是连接符,跳过下一个字符3,表明节点9的左节点是节点3,将栈顶(节点9.原创 2022-05-04 11:31:05 · 448 阅读 · 0 评论 -
二叉树的前中后序遍历
二叉树(英语:Binary tree)是每个节点最多只有两个分支(即不存在分支度大于2的节点)的树结构。通常分支被称作“左子树”或“右子树”。二叉树的分支具有左右次序,不能随意颠倒。这是维基百科给的定义。如上图就是一个二叉树,二叉树的每个节点最多只有两个分支,所以第n层最多2^(n - 1)个节点,而k层总共最多有2^(k + 1) - 1个节点二叉树的遍历分为三种前序遍历中序遍历后序遍历首先要知道,所谓的前序,中序,后序是什么意思?他们是指在遍历过程中中间节点的结果收集或者处理顺序.原创 2022-05-03 08:58:12 · 1477 阅读 · 0 评论