11 2021 档案
摘要:题目 剑指 Offer 42. 连续子数组的最大和 思路1(分析数组的规律) 我们可以从头到尾逐个累加,若之前的累加和小于0,那就从丢弃之前的累加,从当前开始重新累加,同时在遍历过程中比较记录下最大值 curSum记为当前最大值,为 0,以 [-2,1,-3,4,-1,2,1,-5,4] 为例: 首
阅读全文
摘要:题目 剑指 Offer 10- II. 青蛙跳台阶问题 思路1(递归 / 自顶向下) 这题就是和上一题剑指 Offer 10- I. 斐波那契数列基本一模一样,都是 fib(n) = fib(n-1) + fib(n-2) 这个递推公式,只是初始条件不一样啦:上一题是 0、1、1、2...,而本题是
阅读全文
摘要:题目 剑指 Offer 10- I. 斐波那契数列 思路1(递归 / 自顶向下) 这题是很常见的一道入门递归题,可以采用自顶向下的递归方法,比如我们要求第n个位置的值,根据斐波那契数列的定义fib(n) = fib(n-1) + fib(n-2),即等于前一个和前前一个两个的值之和 但是如果直接递归
阅读全文
摘要:题目 剑指 Offer 32 - III. 从上到下打印二叉树 III 思路1 这题又是上一题剑指 Offer 32 - II. 从上到下打印二叉树 II的升级版,要求我们每层的遍历:一层是从左往右,另一层从右往左,因此可以使用一个布尔值flag来记录每次的状态(每次遍历结束后将flag取反),如果
阅读全文
摘要:题目 剑指 Offer 32 - II. 从上到下打印二叉树 II 思路1 和剑指 Offer 32 - I. 从上到下打印二叉树很类似,不过这一题多加了一个条件,就是是要按层来存储节点的 在每次循环的时候要先获取队列中存在多少个元素size,这代表当前层有多少个节点,然后我们再用一个内循环将这些节
阅读全文
摘要:题目 剑指 Offer 32 - I. 从上到下打印二叉树 思路1 BFS广度优先搜索遍历二叉树,使用队列存储节点 算法执行流程如下: 如果root,不为空,先加入队列,否则直接结束(因为一个元素都没有了嘛) 从队列queue中取出队头元素,存入列表res中,然后如果他的左节 / 右节点点不为空,就
阅读全文
摘要:题目 剑指 Offer 55 - II. 平衡二叉树 思路1(后序遍历+剪枝) 这题是上一题剑指 Offer 55 - I. 二叉树的深度的进阶,逻辑代码和那个一样,也是后续遍历,获取两个子节点较大的那个深度再加上当前一层返回给父节点,是自底向上的 也为要求是否为平很二叉树,要保证他的左子树和右子树
阅读全文
摘要:题目 剑指 Offer 55 - I. 二叉树的深度 思路1(DFS) 后续遍历吧,先遍历到最深(递归到末尾返回0),然后从后面一步一步比较取大的值返回,每次返回层数都加1, 执行流程是怎样的:比如其中一个节点左子树为空,右子树有一个叶子节点,那么 0 > 1 ,肯定选 1 ,再加上当前一层 1 ,
阅读全文
摘要:题目 剑指 Offer 54. 二叉搜索树的第k大节点 思路1 二叉搜索树的特性就是中序遍历结果为递增序列,而题目要求的是第 k 大节点,所以就应该是要遍历结果为降序, 按照先遍历左子树、输出节点、遍历右子树得到的是升序结果,要得到降序,需要按照先遍历右子树、输出节点、再遍历左子树即可 什么时候结束
阅读全文
摘要:题目 剑指 Offer 28. 对称的二叉树 思路1 看到这题首先想到可以将二叉树复制一份镜像的,然后进行后续遍历比较两棵树的每一个节点是否相等,但是这样未免太复杂了,因此我们可以用更好的方法来解决 一般来说,二叉树的后续遍历是从左子树开始的,但是我们也可以调换一下位置,从右子树开始递归,这样子和左
阅读全文
摘要:题目 剑指 Offer 27. 二叉树的镜像 思路1(递归) 我们可以使用深度优先搜索,先递归到链表的末尾,然后从末尾开始两两交换。就相当于后续遍历而已 记得要先保存下来node.right节点,因为我们在递归完左边才递归右边,而递归完左边的时候,直接把node.right的指向修改了,如果事先不保
阅读全文
摘要:题目 剑指 Offer 13. 机器人的运动范围 思路1(DFS) 通过DFS递归,先往一个方向递归到最深地方,然后回溯,直到吧所有的条件都访问一遍 我们使用visited数组记录在访问过程中被访问的位置(因为每个位置最多只能访问一次) 然后每次递归都要判断是否满足如下条件: 不超边界,始终坐标位置
阅读全文
摘要:二分法模版及细节 —— 转载自博客园 二分查找算法细节详解 我相信对很多读者朋友来说,编写二分查找的算法代码属于玄学编程,虽然看起来很简单,就是会出错,要么会漏个等号,要么少加个 1。 不要气馁,因为二分查找其实并不简单。思路很简单,细节是魔鬼。 本文以问答的形式,探究几个最常用的二分查找场景:寻找
阅读全文
摘要:题目 剑指 Offer 12. 矩阵中的路径 思路1(回溯、DFS) 这题可以使用回溯+递归来解决,思路如下: 将二维数组的每一个元素都作为起点进行回溯查找 每次查找的时候,都有四个方向,但是上一个方向不能再次被遍历,因此需要将遍历过的位置进行做标记,递归返回的时候再还原 递归过程中要判断一些条件:
阅读全文
摘要:题目 剑指 Offer 52. 两个链表的第一个公共节点 思路1(栈) 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的节点,同时用pre记录上一个节点,直到当前两个栈顶节点不相等,那么pre节点就是他们开始相遇的地方
阅读全文
摘要:题目 剑指 Offer 25. 合并两个排序的链表 思路1 其实就是归并排序中将两个数组合并成一个有序数组 因为两个链表的元素已经是递增了(必要条件),所以我们可以遍历两个链表,判断两个节点的大小关系,然后交替前进,合并到一个新的链表中 因为需要返回一个合并后的新链表,同时我们也无法判断l1、l2两
阅读全文
摘要:题目 剑指 Offer 24. 反转链表 思路1(迭代) 使用一个指针pre指向上一个节点,初始值为null,然后遍历链表,一边遍历一遍交换指针指向: 先用nextNode下下一个节点 然后将cur指向pre 之后将pre指向cur 最后将cur指向nextNode即可完成两个节点的反转 我们遍历整
阅读全文
摘要:题目 剑指 Offer 22. 链表中倒数第k个节点 思路1(栈) 既然要倒数第k个节点,那我们直接把所有节点放到**栈(先进后出)**里面,然后pop弹出k个元素就可以了 代码 class Solution { public ListNode getKthFromEnd(ListNode head
阅读全文
摘要:题目 剑指 Offer 18. 删除链表的节点 思路1(单指针) 首先判断是否删除的节点为第一个,是的话直接返回就行 如果删除的不是第一个,那么就遍历链表。每次遍历的时候我们都要判断一下下一个节点的值是否为要删除的节点的值:如果是的话,将当前节点指向待删除节点的下一个节点,这样子就成功删除了;否则就
阅读全文
摘要:题目 剑指 Offer 48. 最长不含重复字符的子字符串 思路1(动态规划+哈希表) 暴力查找的所花时间复杂度为,太高了,不推荐 这题我们可以使用动态规划,我们定义dp[j]为:以第j个字符为结尾的不包含重复字符的子字符串的最大长度。我们需要从左到右依次扫描字符串中的每个字符,同时
阅读全文
摘要:题目 剑指 Offer 03. 数组中重复的数字 思路1(哈希表) 依次遍历数组,将元素存入哈希表中,如果哈希表中已经存在,那么就找到重复的数 代码 class Solution { public int findRepeatNumber(int[] nums) { HashSet<Integer>
阅读全文
摘要:题目 剑指 Offer 50. 第一个只出现一次的字符 思路1(哈希表) 先遍历一遍字符串,将字符串中的每个字符存入哈希表中,true代表只出现一次,false代表出现多次 统计结束后,然后再顺序遍历一遍字符串,查找哈希表,判断是否只出现一次 代码 class Solution { public c
阅读全文
摘要:题目 剑指 Offer 59 - II. 队列的最大值 思路1(单调队列) 和剑指 Offer 59 - I. 滑动窗口的最大值基本一样,我们使用两个队列来解决问题:一个普通的队列,用于正常的队列操作;一个双端队列,这个队列是用来存储队列中的最大值的 代码 class MaxQueue { Dequ
阅读全文
摘要:题目 剑指 Offer 59 - I. 滑动窗口的最大值 思路1(单调队列) 使用单调(递减)队列,保持队列中的元素是递减顺序,队列头保存的是当前窗口中最大的元素 首先先模拟建立第一个窗口,同时获取第一个窗口的最大值**(就是队头元素)** 然后每次窗口移动的时候都要判断移出去的元素是否是最大的元素
阅读全文
摘要:题目 剑指 Offer 31. 栈的压入、弹出序列 思路1 刚开始看题目没有啥思路,但是我们可以通过按照题目的要求模拟一次操作,就可以找到其中的规律了 我们使用一个栈stack来模拟栈的push和pop操作: 首先肯定要将所有元素一个个入栈,我们可以再入栈的时候根据popped判断是否需要出栈:如果
阅读全文
摘要:题目 剑指 Offer 30. 包含min函数的栈 思路1 使用一个辅助栈min_stack,用来维护栈的最小的元素 每次添加元素入栈时候,data_stack和min_stack都要同时维护 data_stack按照正常的栈压入和弹出顺序,但是min_stack栈不一样,因为要能获取当前栈的最小元
阅读全文
摘要:题目 剑指 Offer 06. 从尾到头打印链表 思路1(递归) 首先先遍历整个脸表,计算出链表的长度(用于初始化数组)。然后进行递归,从链表头部递归到尾部,这期间什么都不做,直到递归到最后一个节点的时候开始返回,开始返回的同时吧当前节点的值加入到res数组 代码 class Solution {
阅读全文
摘要:题目 剑指 Offer 67. 把字符串转换成整数 思路1 根据题意,要解决这题,首先要判断的条件有: 不包括首位空格 第一位必须为:+、-、数字三者其一,否则不合法 数字必须连续的,如果遇到非数字,结束判断 判断结果要在 ~ 之间,如果超过的话,就
阅读全文
摘要:题目 剑指 Offer 66. 构建乘积数组 思路1 按照一般的思路就是将所有的相乘,然后除以每一位数字就是答案,但是题目要求我们不能使用除法,因此我们会想到每次遍历到每个数字的时候,在遍历一遍数组,将除开自己以外的数字相乘,但是这样做的时间复杂度确是,导致超时,因此我们需要想另外一
阅读全文
摘要:题目 剑指 Offer 61. 扑克牌中的顺子 思路1(排序) 先将数组进行排序,排序结束后再遍历: 寻找非0最小值 如果发现非0的数字重复,直接返回false 遍历结束后,如果max-min < 5,则为顺子,否则不是顺子 代码 class Solution { public boolean is
阅读全文
摘要:题目 剑指 Offer 58 - II. 左旋转字符串 思路1(原地翻转) 先将前n个进行翻转,再将后n个进行翻转,最后再整体翻转一遍 我们把他看成两个部分,然后对每个部分都是一个整体,内部不需要翻转,因此我们可以把这题可以看作是剑指 Offer 58 - I. 翻转单词顺序只有两个单词的情况 代码
阅读全文
摘要:题目 剑指 Offer 58 - I. 翻转单词顺序 思路1 假如题目要求我们翻转字符串,那么我们可以从末尾往前开始遍历每一个字符,同时将每一个字符添加到临时空间,最后输出临时空间的数据就完成翻转了,这就是倒叙遍历字符串,即从最末尾开始遍历。但是这一题又有些不同,题目要求是以单词为单位进行翻转字符串
阅读全文