剑指offer算法题
剑指offer算法题
沉浮一湘蕉
心若沉浮,浅笑安然。
展开
-
剑指 Offer 68 - II. 二叉树的最近公共祖先
题目描述:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。//方法:递归+最近公共祖先特点/* 从左右子树分别进行递归,即查找左右子树上是否有p结点或者q结点,就一共有4种情况: 第一种情况:左子树和右子树均找没有p结点或者q结点;或者当前就是p/q; 第二种情况:左子树上没找到,返回右子树的查找结果; 第三种情况:右子树上没找到,返回左子树的查找结果; 第四种情况:左右子树上均能找到,说明此时的p结点和q...原创 2021-08-20 21:13:05 · 82 阅读 · 0 评论 -
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”//方法:递归+二叉搜索树性质+最近公共祖先性质/* 二叉搜索树: 可以快速地找出树中的某个节点以及从根节点到该节点的路径,例如我们需要找到节点 pp: 我们从根节点开始遍历; ...原创 2021-08-20 20:39:24 · 105 阅读 · 0 评论 -
剑指 Offer 67. 把字符串转换成整数 - 解决方案
题目描述:输入一个字符串,包括数字字母符号,可以为空。 //方法1:牛客版/*1、负号“-”与正号“+”只能出现在第一个i=0的位置;2、不能出现除0~9与+、-之外的任何字符;3、不能出现前置零;int StrToInt(string str) { if(str.empty()) return 0; int signal=1; int sum=0; if(str[0]=='-') signal=-1; ...原创 2021-08-16 20:31:01 · 41 阅读 · 0 评论 -
剑指 Offer 66. 构建乘积数组 - 解决方案
题目描述: 给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。//方法1:暴力遍历求解vector<int> multiply(const vector<int>& A) { vector<int>B; int l...原创 2021-08-16 17:08:03 · 156 阅读 · 0 评论 -
剑指 Offer 61. 扑克牌中的顺子
题目描述:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。方法1:...原创 2021-08-16 19:01:02 · 42 阅读 · 0 评论 -
剑指 Offer 59 - I. 滑动窗口的最大值
题目描述:给定一个数组nums和滑动窗口的大小k,请找出所有滑动窗口里的最大值。原创 2021-08-18 15:41:47 · 60 阅读 · 0 评论 -
剑指 Offer 59 - II. 队列的最大值
题目描述:请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。若队列为空,pop_front 和 max_value需要返回 -1//方法:单调队列(双端队列)/* 在插入每一个元素value 时,从队列尾部依次取出比当前元素 value 小的元素,直到遇到一个比当前元素大的元素 value 新数据插入时,将双向队列后部所有比新数据小的元素删除,因...原创 2021-08-18 17:03:40 · 90 阅读 · 0 评论 -
剑指 Offer 58 - II. 左旋转字符串 - 解决方案
题目描述字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。方法1:直接用substr截取class Solution {public: string LeftRotateString(string str, int n) { if (n > str.size()) return str;//注意加判断 .原创 2021-08-16 16:12:24 · 32 阅读 · 0 评论 -
剑指 Offer 58 - I. 翻转单词顺序
题目描述:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。方法1:双指针/* 首先需要进行预处理,判断输入字符串是不是全部空格,如果是,直接输出字符串。 否则, 遍历字符串 s ,记录单词左右索引边界 i , j ; 每确定一个单词的边界,则将其倒着插入添加至单词列表 res ;...原创 2021-08-16 15:49:23 · 50 阅读 · 0 评论 -
剑指 Offer 57 - II. 和为 s 的连续正数序列 - 解决方案
题目描述输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。方法1:暴力法:枚举每个正整数为起点,判断以它为起点的序列和 sum 是否等于target class Solution {public: vector<vector<int> > FindContinuousSequence(int sum) { vector<vec.原创 2021-08-14 16:56:45 · 92 阅读 · 0 评论 -
剑指 Offer 57. 和为 s 的两个数字
题目描述输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。//方法:左右夹逼法,只需要2个指针,两头的数肯定乘积最小,中间的数乘积最大 。时间复杂度 O(N),空间复杂度 O(1)/* 1.left开头,right指向结尾 2.如果和小于sum,说明太小了,left右移寻找更大的数 3.如果和大于sum,说明太大了,right左移寻找更小的数 4.和相等,把left和right的数返...原创 2021-08-14 14:38:36 · 50 阅读 · 0 评论 -
剑指 Offer 55 - I. 二叉树的深度
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。//方法1:递归int TreeDepth(TreeNode* pRoot) { if(pRoot==NULL) { return 0; } return TreeDepth(pRoot->left)>TreeDepth(pRoot->right)?TreeDepth(pRoot->left)+1:TreeDepth(.原创 2021-08-20 23:21:42 · 54 阅读 · 0 评论 -
剑指 Offer 54. 二叉搜索树的第 k 大节点
给定一棵二叉搜索树,请找出其中第k大的节点。//方法1:递归中序遍历int count=0;//记录遍历了多少个TreeNode* kNode=NULL; //记录下节点 void midOrder(TreeNode* root,int k){ if(root) { midOrder(root->left,k); count++; if(count==k) { kNode=root; } midOrder(root->right,k); }原创 2021-08-21 19:37:33 · 162 阅读 · 0 评论 -
剑指 Offer 53 - II. 0~n-1 中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。原创 2021-08-13 20:57:58 · 41 阅读 · 0 评论 -
剑指 Offer 53 - I. 在排序数组中查找数字
统计一个数字在排序数组中出现的次数。原创 2021-08-09 14:40:23 · 79 阅读 · 0 评论 -
剑指 Offer 45. 把数组排成最小的数
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。/* 本质上是一个排序问题。设数组nums中任意两数字的字符串为 x 和 y,则规定排序判断规则为: 若拼接字符串 x + y > y + x,则 x“大于”y ; 反之,若 x + y < y + x,则 x “小于”y ; 其中,x “小于” y代表:排序完成后,数组中 x应在 y左边;“大于” 则反之。 算法流程: 1.初始化: 字...原创 2021-07-29 16:24:25 · 112 阅读 · 0 评论 -
剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。方法1:数组排序:首先将 nums 排序,由于该数字超过数组长度的一半,所以数组的中间元素就是答案,时间复杂度为 O(nlogn),空间复杂度:O(1)int MoreThanHalfNum_Solution(vector<int> numbers) { int len=numbers.size(); int res=len/2;//子数组超过原数组的一半,所以原创 2021-07-19 16:33:51 · 106 阅读 · 0 评论 -
剑指 Offer 31. 栈的压入、弹出序列
题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。//方法:辅助栈+模拟 三种情况分类讨论: 1.如果push和pop相同,则同时后移。 2. 如果push和pop不相同,但是pop和栈顶相同,则出栈...原创 2021-08-17 16:55:42 · 56 阅读 · 0 评论 -
剑指 Offer 30. 包含 min 函数的栈 - 解决方案
题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。 !!注意:题目意思是可以获取栈内最小数,而不是对栈内数据进行排序。方法:开辟一个辅助栈class Solution {public: stack<int> nomal_stack,min_stack; void push(int value) { nomal_stack.push(val...原创 2021-08-17 15:22:13 · 97 阅读 · 0 评论 -
剑指 Offer 29. 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。方法:循环遍历整个数组,循环中再嵌套四个循环,分别是从左至右,从上至下,从右至左,从下至上这几个方向,按照题意将整个数组遍历完成,控制好边界。时间复杂度:O(mn),空间复杂度:O(1)vector<int> printMatrix(vector<vector<int> > matrix) { int bottom=matrix.size()-1; int right=matrix[0].s原创 2021-07-19 10:56:17 · 43 阅读 · 0 评论 -
剑指 Offer 28. 对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。//方法:递归/* 若满足对称二叉树,必须满足: 1. L->val == R->val 2. L->left->val == R->right->val 3. L->right->val == R->left->val 因此可以自顶向下,递归求解即可。 设置一个递归函数isSame(r1,...原创 2021-08-20 22:58:30 · 70 阅读 · 0 评论 -
剑指 Offer 27. 二叉树的镜像
请完成一个函数,输入一个二叉树,该函数输出它的镜像。方法1:递归遍历/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */ TreeNode* Mirror(TreeNode* pRoot) { TreeNode* temp;原创 2021-08-18 18:43:55 · 46 阅读 · 0 评论 -
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。方法1:不要求稳定性:用前后指针分别指向偶数、奇数,然后数字互换 (时间复杂度:O(n),空间复杂度:O(1))class Solution {public: vector<int> exchange(vector<int>& nums) { int len=nums.size(); i...原创 2021-07-18 21:43:28 · 40 阅读 · 0 评论 -
剑指 Offer 17. 打印从 1 到最大的 n 位数
输入数字n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。方法1:直接计算出n位数的最大值,然后依次输出/* 1.最大的n位数(记为 end)和位数 n的关系: end=10^n-1。 2.大数越界问题: 当n较大时,end会超出 int32整型的取值范围,超出取值范围的数字无法正常存储。由于本题要求返回 int 类型数组,相当于默认所有数字都在 int32 整型取值范围内,因此不考虑大数越界问题。*/cl...原创 2021-07-17 20:28:43 · 115 阅读 · 0 评论 -
剑指 Offer 11. 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组[3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。方法1:暴力查找最小值(时间复杂度O(n),空间复杂度O(n))class Solution {public: int minNumberInRotateArray(vector<int> rotateArray) { int min=0;.原创 2021-07-17 15:50:59 · 49 阅读 · 0 评论 -
剑指 Offer 09. 用两个栈实现队列
题目描述用两个栈来实现一个队列,分别完成在队列尾部插入整数(push)和在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。class Solution{ public: void push(int node) { stack1.push(node); } int pop() { if(stack2.empty())//记得加判断 { whil原创 2021-08-16 21:37:30 · 51 阅读 · 0 评论 -
剑指 Offer 06. 从尾到头打印链表
题目描述输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。//方法1:递归vector<int> ans;void recur(ListNode* head){ if(head==NULL) return; recur(head->next); ans.emplace_back(head->val);}vector<int> printListFromTailToHead(List...原创 2021-08-16 21:08:12 · 55 阅读 · 0 评论 -
剑指 Offer 05. 替换空格
请实现一个函数,把字符串s中的每个空格替换成"%20"。方法1:由前向后遍历(时间复杂度为O(n^2))class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @return string字符串 */ string replaceSpace(string s) { /..原创 2021-07-12 22:52:46 · 51 阅读 · 0 评论 -
剑指 Offer 04. 二维数组中的查找
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。方法1:暴力(时间复杂度:O(nm),空间复杂度:O(1))直接遍历整个二维数组的每一个元素,判断目标值是否在二维数组中存在。class Solution {public: bool Find(int target, vector<vector<int> > array) {原创 2021-07-12 14:39:32 · 56 阅读 · 0 评论