
算法题
文章平均质量分 60
程序员Seven
欢迎到访在线网站:www.seven97.top
Java八股文面试材料获取,欢迎关注公众号 SevenCoding
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
剑指offer-25、复杂链表的复制
输⼊⼀个复杂链表(每个节点中有节点值,以及两个指针,⼀个指向下⼀个节点,另⼀个特殊指针random 指向⼀个随机节点),请对此链表进⾏深拷⻉,并返回拷⻉后的头结点。(注意,输出结果中请不要返回参数中的节点引⽤,否则判题程序会直接返回空)原创 2025-08-27 09:00:00 · 81 阅读 · 0 评论 -
剑指offer-24、二叉树中和为某一值的路径(一)
输⼊⼀颗⼆叉树的根节点和⼀个整数,按字典序打印出⼆叉树中结点值的和为输⼊整数的所有路径。路径定义为从树的根结点开始往下⼀直到叶结点所经过的结点形成⼀条路径。返回true ,因为存在⼀条路径 5 -> 4 -> 11 -> 2 的节点值之和为 22。例如:给出如下二叉树,sum=22。原创 2025-08-26 09:00:00 · 238 阅读 · 0 评论 -
剑指offer-23、搜索⼆叉树的后序遍历序列
注意是⼆叉搜索树,如果是后续遍历的话,那么应该最后⼀个元素是中间元素 mid ,前⾯的元素可以分为两部分,⼀部分⽐ mid ⼩,另⼀部分全部⽐ mid ⼤。输⼊⼀个整数数组,判断该数组是不是某⼆叉搜索树的后序遍历的结果。假设输⼊的数组的任意两个数字都互不相同。需要判断给定的整数数组是否是某个二叉搜索树(BST)的后序遍历结果。后序遍历的顺序是:左子树 → 右子树 → 根节点,因此数组的最后一个元素一定是根节点。说明:是上图的后序遍历 ,返回true。输⼊:[1,3,2]原创 2025-08-20 09:00:00 · 315 阅读 · 0 评论 -
剑指offer-22、从上往下打印⼆叉树
从上往下打印出⼆叉树的每个节点,同层节点从左⾄右打印。这个其实就是标准的迭代遍历了。原创 2025-08-19 09:00:00 · 179 阅读 · 0 评论 -
剑指offer-21、栈的压⼊、弹出序列
假设压⼊栈的所有数字均不相等。例如序列1,2,3,4,5 是某栈的压⼊顺序,序列4,5,3,2,1 是该压栈序列对应的⼀个弹出序列,但4,3,5,1,2 就不可能是该压栈序列的弹出序列。说明:可以通过push(1) => push(2) => push(3) => push(4) => pop() => push(5)=> pop() => pop() => pop() => pop();这样的顺序得到 [4,5,3,2,1] 这个序列,返回 true。输⼊:[1,2,3,4,5],[4,5,3,2,1]原创 2025-08-13 09:00:00 · 125 阅读 · 0 评论 -
剑指offer-20、包含min函数的栈
pop ⼀个元素的时候,如果栈为空则什么都不操作,如果栈不为空,则判断datas 的第⼀个元素是否和mins 的第⼀个元素相等。如果相等的话那么就需要将mins 和datas pop 出去第⼀个元素,否则只需要将datas 的第⼀个元素 pop 出去即可。push ⼀个元素的时候,都需要push 进datas stack ,但是push 进⼊mins stack 需要满⾜条件:当前的mins stack 是空的,直接放⼊。或者当前的mins stack 的栈顶元素⼤于或者等于push 进来的值。原创 2025-08-12 09:00:00 · 248 阅读 · 0 评论 -
剑指offer-19、顺时针打印矩阵
我们使⽤的是不断缩⼩矩阵上,下,左,右四个边界的⽅法。⾸先定义⼀个up (上边界为0 ), down (下边界为matrix.length - 1 ), left (左边界为0 ), right (右边界为matrix[0].length - 1 )。从第⼀个⾏第⼀个开始打印,向左边界遍历到右边界,之后将上边界加上1 (因为已经遍历完成上边界⼀⾏),判断上边界加上⼀之后是否⼤于下边界,如果是则调出。则依次打印出数字 1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10 .原创 2025-08-06 09:00:00 · 262 阅读 · 0 评论 -
剑指offer-18、⼆叉树的镜像
操作给定的⼆叉树,将其变换为源⼆叉树的镜像。⼆叉树的镜像定义:源⼆叉树。原创 2025-08-05 09:00:00 · 147 阅读 · 0 评论 -
剑指offer-17、树的⼦结构
输⼊两棵⼆叉树A , B ,判断B 是不是A 的⼦结构。(ps:我们约定空树不是任意⼀个树的⼦结构)原创 2025-07-30 09:00:00 · 243 阅读 · 0 评论 -
剑指offer-16、合并两个有序链表
使用两个指针分别遍历两个链表,比较当前节点的值,将较小的节点连接到结果链表上。当一个链表遍历完后,将另一个链表的剩余部分直接连接到最后。利用递归将问题分解:每次比较两个链表的头节点,选择较小的节点作为合并后链表的头节点,然后递归地合并剩余部分。输⼊两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满⾜单调不减规则。原创 2025-07-29 09:00:00 · 136 阅读 · 0 评论 -
剑指offer-14、链表中倒数第k个结点
方法时间复杂度空间复杂度优点缺点两次遍历法O(n)O(1)实现简单需要两次遍历双指针法O(n)O(1)一次遍历,效率高边界条件需仔细处理栈辅助法O(n)O(n)实现直观空间开销大递归回溯法O(n)O(n)展示递归思想空间效率低。原创 2025-07-23 09:00:00 · 415 阅读 · 0 评论 -
剑指offer-13、调整数组顺序使奇数位于偶数前面(一)
方法时间复杂度空间复杂度优点缺点辅助数组法O(n)O(n)实现简单,顺序有保证空间开销大双指针原地排序O(n²)O(1)空间效率高时间效率低两次遍历填充法O(n)O(n)时间效率高空间开销中等稳定双指针交换法O(n²)O(1)空间效率高实现复杂,时间效率低优化双指针法O(n²)O(1)空间效率高,顺序保证好时间效率低。原创 2025-07-22 09:00:00 · 420 阅读 · 0 评论 -
剑指offer-12、数值的整数次方
题⽬中的 double 类型不能拆解,但是 int 类型的整数 exponet 可以做点⽂章,我们平时求次⽅的时候,假设有个 x 的 4 次⽅,我们通常是求出⼀个 x 的平⽅数 x^2 ,然后两个 x^2相乘就可以得出 x^4。给定⼀个 double 类型的浮点数 base 和 int 类型的整数 exponent。例如,计算3¹³(1101₂)可以分解为3⁸ * 3⁴ * 3¹。如果指数是负数,则先取反,最后取结果的倒数即可。如果使⽤暴⼒解答,那么就是不断相乘,对于负数⽽⾔,则是相除,并且符号取反。原创 2025-07-16 09:00:00 · 336 阅读 · 0 评论 -
剑指offer-11、⼆进制中1的个数
⽐如7的⼆进制是111 ,那么7&6=111&110=110=6 ,就完美把最后⼀位1 变成0 了, 6 的⼆进制是110 , 6&5=110&101=100=4 ,也把最后⼀位1 变成了0。说明:负数使⽤补码表示 ,-1的32位⼆进制表示为1111 1111 1111 1111 1111 1111 1111 1111,其中32个1。说明:⼗进制中10的32位⼆进制表示为0000 0000 0000 0000 0000 0000 0000 1010,其中有两个1。可以消除最右边的1的特性,直到n变为0。原创 2025-07-15 09:00:00 · 318 阅读 · 0 评论 -
剑指offer-10、矩阵覆盖
显然,这形成了一个类似斐波那契数列的规律:f(n) = f(n-1) + f(n-2)。我们可以用 2 * 1 的小矩形横着或者竖着去覆盖更大的矩形。我们需要用若干个2×1的小矩形(可以横放或竖放)无重叠地覆盖一个2×n的大矩形,求总共有多少种不同的覆盖方法。观察发现,计算f(n)只需要前两个状态f(n-1)和f(n-2),因此可以用两个变量代替整个数组,将空间复杂度优化到O(1)。因此,总方法数为这两种情况之和:f(n) = f(n-1) + f(n-2),这正是斐波那契数列的递推关系。原创 2025-07-09 09:00:00 · 483 阅读 · 0 评论 -
剑指offer-9-变态跳台阶
本文探讨了青蛙跳台阶问题的多种解法。该问题要求计算青蛙跳上n级台阶的总跳法数,每次可跳1到n级。通过数学归纳发现规律f(n)=2^(n-1),直接得出O(1)的最优解。递归法将问题分解为子问题,但存在O(n)时间/空间复杂度。动态规划优化了递归,采用迭代方式存储中间结果(O(n)空间)。进一步优化为仅保存前一个状态,实现O(1)空间的最优迭代解法。各种方法展现了从数学观察到算法优化的完整思路,其中优化的动态规划解法最适合实际应用。原创 2025-07-08 09:00:00 · 350 阅读 · 0 评论 -
剑指offer-8、跳台阶
⼀只⻘蛙⼀次可以跳上1级台阶,也可以跳上2级。求该⻘蛙跳上⼀个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。解释:⻘蛙要跳上两级台阶有两种跳法,分别是:先跳⼀级,再跳⼀级或者直接跳两级。这题和第7题 斐波那契数列 基本类似,只是换了一个题目表达方式。观察状态转移方程,发现当前状态仅依赖前两个状态(),因此只需保存这两个值,无需存储整个数组。原创 2025-07-02 09:00:00 · 137 阅读 · 0 评论 -
剑指offer-6、旋转数组的最小数字
取出中间元素,和最右边元素⽐较,如果中间元素⼤于最右边元素,则证明,最⼩值存在于中间元素到最右边元素之间的⼀段。如果中间元素⼩于最右边元素,则证明,最⼩值在最左边元素到中间元素之间的⼀段中。旋转之后的数组其实就是分成两段,⽐如 {3,4,5,1,2} ,可以看到, 3 , 4 , 5 是递增的,但是 5之后1 就是⽐之前的数⼩的,这样就可以找到最⼩值 1。例如数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的⼀个旋转,该数组的最⼩值为 1。原创 2025-06-26 09:00:00 · 493 阅读 · 0 评论 -
剑指offer-5、两个栈实现⼀个队列
⽤两个栈来实现⼀个队列,完成队列的 Push 和 Pop 操作。队列中的元素为 int 类型。但是依然还是要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用来备份的!所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。有两个栈 stack1 , stack2;其实这道题目就是用一个队列就够了。原创 2025-06-25 09:00:00 · 177 阅读 · 0 评论 -
剑指offer-4、重建二叉树
看上⾯的图⽚,⾸先数据保证了正确性,那么前序的第⼀个肯定是root 节点,也就是1 ,那么就需要在中序遍历中找到1 的位置,左边就是这个root 的左⼦树,右边就是root 的右⼦树。我们可以⼀开始创建⼀个栈,分别⽤两个指针执⾏前序遍历和中序遍历的第⼀个元素,先将前序遍历的第⼀个元素压⼊栈中,因为前序遍历的特性,第⼀个元素肯定是根节点。直到,中序遍历的第⼀个元素 4 ,已经等于栈顶元素 4 ,说明4 没有左⼦树了,因为 4 是在中序遍历⾥⾯,中序遍历完根节点,剩下的部分只能是右⼦树。原创 2025-06-24 09:00:00 · 502 阅读 · 0 评论 -
剑指offer-3、从尾到头打印链表
前⾯我们能想到栈,那么我们何必⾃⼰实现呢?先把元素⾥⾯的元素从头到尾遍历取出放在栈⾥⾯,然后再把栈的元素去出来放在ArraList ⾥⾯。主要利⽤了栈的先进后出的规则,这样就可以实现倒序的功能。遍历每⼀个节点,然后把它插⼊到头部,这样⼀直遍历到尾的时候,就相当于将整个链表都反转⼀遍了,然后再从头到尾遍历放到ArryList 即可。输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。0 <= 链表长度 <= 10000。返回一个数组为[3,2,1]原创 2025-06-17 09:00:00 · 247 阅读 · 0 评论 -
剑指offer-2、替换空格
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为"We Are Happy",则经过替换之后的字符串为"We%20Are%20Happy"。对字符串进行遍历,然后使用StringBuilder进行字符串的拼接,遇到空格添加。java ⾥⾯有可以直接使⽤的函数replace() ,直接写成下⾯这样即可通过。但是这里用到了额外的空间,额外用到StringBuilder进行存储。原创 2025-06-13 09:00:00 · 161 阅读 · 0 评论 -
剑指offer-1、⼆维数组中的查找
在⼀个⼆维数组中(每个⼀维数组的⻓度相同),每⼀⾏都按照从左到右递增的顺序排序,每⼀列都按照从上到下递增的顺序排序。请完成⼀个函数,输⼊这样的⼀个⼆维数组和⼀个整数,判断数组中是否含有该整数。题目提示了,每⼀⾏都按照从左到右递增的顺序排序,每⼀列都按照从上到下递增的顺序排序,那我们其实就可以利用矩阵的排序特性可以从右上角或左下角开始查找,从而优化搜索效率。而如果是从左上角开始找,这种两个方向都更大, 如果从右下角开始找,两个方向都更小,显然无法完成搜索。- 如果当前元素大于目标值,向左移动一列。原创 2025-06-06 09:00:00 · 131 阅读 · 0 评论 -
算法题:数组中的第k个最大元素
很显然,nums[i] 最终所在的位置,也就是它排序后的具体位置。也就是说,如果实现的排序是降序排序,那么第k个位置的数据,也确定就是第k大的。而这样每经过一次 partition操作就能缩小搜索的范围,这样的思想叫做 “减而治之”(是 “分而治之” 思想的特例)。你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。但是,如果出了这道题,显然不是想让你调 API ,而是看你对快排的理解。个元素中最小的,有就是所有元素中第 k。请注意,你需要找的是数组排序后的第。原创 2025-06-05 09:00:00 · 391 阅读 · 0 评论 -
从尾到头打印链表
前⾯我们能想到栈,那么我们何必⾃⼰实现呢?先把元素⾥⾯的元素从头到尾遍历取出放在栈⾥⾯,然后再把栈的元素去出来放在ArraList ⾥⾯。主要利⽤了栈的先进后出的规则,这样就可以实现倒序的功能。遍历每⼀个节点,然后把它插⼊到头部,这样⼀直遍历到尾的时候,就相当于将整个链表都反转⼀遍了,然后再从头到尾遍历放到ArryList 即可。输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。0 <= 链表长度 <= 10000。返回一个数组为[3,2,1]原创 2025-05-29 09:00:00 · 485 阅读 · 0 评论 -
反转链表(花式反转)
最好的方式还是双指针解法;如果数据量较大,递归解法和借用栈的方式都有可能导致栈溢出的情况。原创 2025-05-21 09:00:00 · 794 阅读 · 0 评论 -
手写生产者消费者模型
生产者-消费者模式是一个十分经典的多线程并发协作模式,弄懂生产者-消费者问题能够让我们对并发编程的理解加深。这也是校招常见面试手撕题所谓的生产者-消费者,实际上包含了两类线程,一种是生产者线程用于生产数据,另一种是消费者线程用于消费数据,为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库,生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为;而消费者只需要从共享数据区中获取数据,不需要关心生产者的行为。如果共享数据区已满的话,阻塞生产者继续生产数据;原创 2025-05-14 09:15:00 · 1050 阅读 · 0 评论 -
编写一段代码,使其必定产生死锁
编写一段代码,使得这段代码必定会产生死锁。原创 2025-05-07 09:15:00 · 403 阅读 · 0 评论