剑指offer
浅忆carollion
随心 随性
展开
-
101. 对称二叉树
101. 对称二叉树解题思路:首先我们引入一个队列,这是把递归程序改写成迭代程序的常用方法。初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。public: bool check(TreeNode* root1,TreeNode* root2) { queu原创 2021-05-07 21:36:05 · 74 阅读 · 0 评论 -
剑指 Offer 45. 把数组排成最小的数
剑指 Offer 45. 把数组排成最小的数解题思路:自定义排序本题主要求两数拼接起来最小的数字,设nums中任意两数字的字符串为x,y;若拼接后的字符串x+y > y+x,则定义为x“大于”y;反之,若x+y < y+x,则定义为x“小于”y。根据以上规则对nums数组进行排序,使用快排。算法流程:初始化:首先将nums数组中的所有数字初始化到字符串列表vector strs中。进行排序:使用快排(本文使用的是挖坑填补法),对strs中的字符串按照以上规则进行排序。将原创 2021-04-20 16:05:05 · 72 阅读 · 0 评论 -
剑指 Offer 57. 和为s的两个数字
剑指 Offer 57. 和为s的两个数字解题思路:算法流程:初始化: 双指针 i , j 分别指向数组 nums的左右两端 (俗称对撞双指针)。循环搜索: 当双指针相遇时跳出;1)计算和 s = nums[i] + nums[j];2)若 s > target,则指针 j 向左移动,即执行 j = j - 1;3)若 s < target ,则指针 i 向右移动,即执行 i = i + 1;4)若 s = target,立即返回数组 [nums[i], nums[j]]]原创 2021-04-17 19:07:28 · 60 阅读 · 0 评论 -
剑指 Offer 56 - II. 数组中数字出现的次数 II
剑指 Offer 56 - II. 数组中数字出现的次数 II集体思路:使用哈希表算法流程:使用哈希表将nums中的数值和是否出现多次映射。每次映射查找n是否已在哈希表中,在则将此值记为false,否则true.遍历nums,查找nums值对应的哈希表res[nums]是否为真,为真则返回结果nums.class Solution {public: int singleNumber(vector<int>& nums) { //使用哈希表原创 2021-04-17 18:42:30 · 45 阅读 · 0 评论 -
剑指 Offer 56 - I. 数组中数字出现的次数
剑指 Offer 56 - I. 数组中数字出现的次数解题思路:算法流程:全部异或,然后相同为0,不同为1,最后得到的结果就是两个不同数的异或结果ans。将异或结果位于1判断哪位为1,根据异或为1的那位将nums中的数分为此位为1和此位为0的两部分。然后两部分分别异或得到不同的数。将两数加入列表res,返回结果列表res。class Solution {public: vector<int> singleNumbers(vector<int>&原创 2021-04-17 18:18:29 · 50 阅读 · 0 评论 -
剑指 Offer 55 - I. 二叉树的深度
剑指 Offer 55 - I. 二叉树的深度解题思路:递归+回溯算法流程:dfs(TreeNode* root,int tmp)函数递归;终止条件: 若节点 root 为空,则直接返回。递推工作:1)深度更新:tmp初始值为根节点1,递推tmp+1;2)先序遍历: 递归左 / 右子节点。5)集合更新: 向上回溯前,需要将当前节点的深度加入集合res中,即res.insert(tmp);调用函数dfs,返回集合res中的最大值,即最后一个值*(res.end()).class So原创 2021-04-17 17:32:29 · 41 阅读 · 0 评论 -
剑指 Offer 34. 二叉树中和为某一值的路径
剑指 Offer 34. 二叉树中和为某一值的路径解题思路:回溯法(递归先序遍历二叉树)-. 先序遍历:按照“根、左、右”的节点遍历二叉树。-. 记录路径:遍历节点记录路径上所有节点的和sum,当sum==target并且遍历到叶子结点,则将此路径path加入结果列表res。算法流程:dfs(root, tmp,target) 函数:递推参数: 当前节点 root ,当前目标值 target。终止条件: 若节点 root 为空,则直接返回。递推工作:1)路径更新: 将当前节点值 roo原创 2021-04-16 21:36:28 · 47 阅读 · 0 评论 -
剑指 Offer 32 - III. 从上到下打印二叉树 III
剑指 Offer 32 - III. 从上到下打印二叉树 III解题思路:借助辅助队列和栈,使用特殊标记隔离每层,使用变量i记录层数。借助队列和栈的特点,将奇数层的从队列弹出打印,将偶数层的从栈弹出打印。将根节点和特殊标记入队,同时记录当前层数为1。队列和栈同时空跳出循环:1)当前层为奇数层,从队列弹出节点,将节点加入volum,同时将非空左右节点入队,若弹出节点为标志则将volum加入res,清空volum,然后层数+1,弹出标致判断队列非空将标志加入队列。2)当前层数为偶数层,循原创 2021-04-14 23:28:23 · 94 阅读 · 0 评论 -
剑指 Offer 44. 数字序列中某一位的数字
剑指 Offer 44. 数字序列中某一位的数字解题思路输入第n位首先找出第n位对应的数字位数,然后根据位数找到此位所对数值num,然后找到n所对num中的第几位数字.1. 第一步确定所求数位的所在数字的位数digit为1位的数共有10个(0-9),2位的共有90个(10-99),三位的共有900个(100-999)…然后每位所对位数的所有数字位数和count分别是:digit为1共有101位,digit为2共有902位,digit为3的共有900*3位…;则起始数值start分别是0,10,10原创 2021-04-13 09:53:41 · 95 阅读 · 0 评论 -
剑指 Offer 32 . 从上到下打印二叉树
剑指 Offer 32 - I. 从上到下打印二叉树解题思路:采用层序遍历的思想,借助辅助队列完成节点打印.当树的根节点为空,则直接返回空列表 [] ;先将根节点入队队列空则跳出循环:弹出队首节点node,将node的值加入列表res中,然后将node的非空左右节点入队.返回res列表.class Solution {public: vector<int> levelOrder(TreeNode* root) { //层序遍历二叉树打印 借助辅助队列原创 2021-04-12 15:50:20 · 51 阅读 · 0 评论 -
剑指 Offer 38. 字符串的排列
剑指 Offer 38. 字符串的排列题目:输入一个字符串,打印出该字符串中字符的所有排列。你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。示例:输入:s = “abc”输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]解题思路:排列方案的生成:对于一个长度为n的字符串,根据字符串排列的特点,考虑深度优先搜索所有排列方案。即通过字符交换,先固定第 11位字符( n 种情况)、再固定第 2 位字符( n-1种情况)、… 、最后固定第 n 位字符( 1原创 2021-04-10 21:03:16 · 84 阅读 · 0 评论 -
剑指 Offer 37. 序列化二叉树
剑指 Offer 37. 序列化二叉树解题思路序列化二叉树:首先判断树是否为空,空则直接返回"[]".借助辅助队列,层序遍历二叉树,首先将"["加入str,并将根节点入队.队列空则结束:1)获取队列首节点node,将首节点弹出.2)判断node是否为空,空则直接将"null"加入字符串str,非空则将当前节点node的值val加入字符串,并将node的左右子树节点加入队列.3)判断队列是否为空,非空将","加入str.跳出循环将"]"加入str.最后返回str.原创 2021-04-10 16:02:52 · 58 阅读 · 0 评论 -
剑指 Offer 31. 栈的压入、弹出序列
剑指 Offer 31. 栈的压入、弹出序列解题思路借助辅助栈,首先遍历入栈顺序表,将元素依次入辅助栈,在入栈的过程中入一个判断栈顶元素是否等于出栈顺序表中的第一个元素,若相等,则将栈顶元素出栈,出栈表索引+1,否则,继续入栈。直到则内没有元素则弹出序列是该入栈序列的一个弹出序列。算法流程:初始化: 辅助栈 stackstack ,弹出序列的索引 i;遍历压栈序列: 各元素记为 num;1>.元素 num入栈;2>.循环出栈:若 stack 的栈顶元素 == 弹出序列元素 3&原创 2021-04-09 09:16:21 · 49 阅读 · 0 评论 -
剑指 Offer 36. 二叉搜索树与双向链表
剑指 Offer 36. 二叉搜索树与双向链表题目描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的原创 2021-04-07 23:36:03 · 60 阅读 · 0 评论 -
剑指 Offer 42. 连续子数组的最大和
剑指 Offer 42. 连续子数组的最大和解题思路:使用动态规划状态定义: 设动态规划列表 dp ,dp[i] 代表以元素 num[i] 为结尾的连续子数组最大和。为何定义最大和 dp[i]中必须包含元素 nums[i] :保证 dp[i] 递推到 dp[i+1] 的正确性;如果不包含 nums[i],递推时则不满足题目的 连续子数组 要求。转移方程: 若 dp[i−1]≤0 ,说明 dp[i - 1] 对 dp[i]产生负贡献,即 dp[i-1] + nums[i]还不如 nums[i] 本身原创 2021-04-05 17:09:13 · 49 阅读 · 0 评论 -
面试题30. 包含min函数的栈
面试题30. 包含min函数的栈解题思路:本题难点在于调用 min、push 及 pop 的时间复杂度都是 O(1)。栈调用push和pop复杂度就是O(1),但是要实现min()函数需要遍历栈对比,时间复杂度是Q(N),则要实现O(1)可以定义两个栈,一个数据栈A和一个辅助栈B。数据栈 AA : 栈 AA 用于存储所有元素,保证入栈 push() 函数、出栈 pop() 函数、获取栈顶 top() 函数的正常逻辑。辅助栈 BB : 栈 BB 中存储栈 AA 中所有 非严格降序 的元素,则栈 A原创 2021-04-04 19:44:53 · 62 阅读 · 0 评论 -
剑指 Offer 09. 用两个栈实现队列
剑指 Offer 09. 用两个栈实现队列解题思路:首先定义两个栈stack1、stack2,一个作为入队栈(stack1)一个作为出队栈(stack2),在CQueue函数中将两个站初始化,然后在appendTail()函数实现入队操作,在deleteHead()函数中实现出队操作。appendTail:入队操作,先判断出队栈stack2中是否为空,若不空则将stack2中的所有元素弹出加入到stack1中,然后再往stack1中插入元素;否则直接插入stack1.deleteHead:出队操原创 2021-04-03 14:44:10 · 41 阅读 · 0 评论 -
剑指 Offer 29. 顺时针打印矩阵
剑指 Offer 29. 顺时针打印矩阵题解首先定义四个变量left,right,top,bottom代表左右上下四个边界,依次从左向右遍历,然后边界值缩进,从上向下,从右向左,从下向上以此类推直到边界条件不满足跳出。算法流程:空值处理: 当 matrix 为空时,直接返回空列表 [] 即可。初始化: 矩阵 左、右、上、下 四个边界 l , r , t , b,用于打印的结果列表 res 。循环打印: “从左向右、从上向下、从右向左、从下向上” 四个方向循环,每个方向打印中做以下三件事(各方原创 2021-04-01 22:52:22 · 50 阅读 · 0 评论 -
剑指 Offer 28. 对称的二叉树
剑指 Offer 28. 对称的二叉树解题思路:对称二叉树定义: 对于树中 任意两个对称节点 L 和 R ,一定有:1.L.val = R.val :即此两对称节点值相等。2.L.left.val = R.right.val :即 L 的 左子节点 和 R 的 右子节点 对称;3.L.right.val = R.left.val :即 L 的 右子节点 和 R 的 左子节点 对称。根据以上规律,考虑从顶至底递归,判断每对节点是否对称,从而判断树是否为对称二叉树。算法流程:isSymmet原创 2021-03-30 17:10:12 · 55 阅读 · 0 评论