剑指offer
流星空
成功与否不在于你的天赋有多高,专业有多对口,而在于你舍不舍得花时间和精力去做好一件事,愿不愿意通过不懈努力证明没有什么是做不到的。
展开
-
dfs&&bfs&&leetcode200. 岛屿数量
题目链接:200. 岛屿数量c++用久了,拿javascript刷下题,这题看别人的面经被问到过……原创 2021-10-18 10:55:37 · 217 阅读 · 0 评论 -
暴力&&动规&&剑指 Offer 63. 股票的最大利润
起初遍历查找最小值和最小值之后的最大值,返回差值,但测试用例 [2,4,1]就过不了了;随后看着跟上升数组有关,试了一下O(n^2)时间复杂度的遍历方法,居然过了。暴力class Solution {public: int maxProfit(vector<int>& prices) { int ans=0,size=prices.size(); for(int i=0;i<size-1;i++){ int tm原创 2021-09-22 00:15:13 · 91 阅读 · 0 评论 -
动规&&剑指 Offer 60. n个骰子的点数
参考解答:剑指 Offer 60. n 个骰子的点数(动态规划,清晰图解)1.暴力解答需要遍历所有点数,时间复杂度不允许。2.动规正向递推:n个骰子的概率列表 等于 n-1个骰子的概率 加上 新增一个骰子从1到6点数变化概率的叠加class Solution {public: vector<double> dicesProbability(int n) { //n个数的加法组合,暴力超时 vector<double>dp(6,1.0/原创 2021-09-21 10:55:23 · 97 阅读 · 0 评论 -
递推&&剑指 Offer 66. 构建乘积数组
递推class Solution {public: vector<int> constructArr(vector<int>& a) { //递推,《算法与程序设计》课上遇到过,一时半会忘了 /*找规律 a1a2a3a4 a2a3a4 a0 a3a4 a0a1 a4 a0a1a2 a0a1a2a3原创 2021-09-20 16:46:41 · 77 阅读 · 0 评论 -
双端队列&&剑指 Offer 59 - II. 队列的最大值
max()的O(1)时间实现,想不到呀,单栈最大值出队时无法得知下一个最大值,遍历最大值需要O(n)时间复杂度。参考:剑指 Offer 59 - II. 队列的最大值(单调双向队列,清晰图解)1.暴力解法,实现一个队列,max()方法最坏的时间复杂度仍是O(n)。2.双端队列双端队列的正确性:原数组按顺序存储弹出,故双端队列记录的是数组一段窗口的最大值。为什么需要双端队列?因为涉及到需要弹出尾部元素和首部元素的操作。双端队列使用:C++ deque的用法与示例class MaxQueue {原创 2021-09-17 23:36:42 · 127 阅读 · 0 评论 -
dp&&剑指 Offer 49. 丑数
难点:只包含质因子:2、3、5.。思路:n个丑数的子集合乘以2/3/5仍是丑数,即:下一个丑数是从前面某个丑数中乘以2/3/5,且大于当前丑数推出来的,不是遍历判断出来的。参考:剑指 Offer 49. 丑数(动态规划,清晰图解)class Solution {public: int nthUglyNumber(int n) { //a,b,c记录的是丑数,因此需要建立一个列表记录丑数 int a=0,b=0,c=0; vector<in原创 2021-09-17 16:10:47 · 92 阅读 · 0 评论 -
set&&剑指 Offer 48. 最长不含重复字符的子字符串
做过类似题目。1.set过了,但是冗余操作占用比较大的时间复杂度。发现set的size()方法返回值不是(signed) (int)类型,而是unsigned long (int)类型。参考:C++ 查看变量数据类型之 typeid().name()class Solution {public: int lengthOfLongestSubstring(string s) { //做过类似题目,用set试试 set<char> str;原创 2021-09-17 15:09:30 · 102 阅读 · 0 评论 -
dp&&剑指 Offer 47. 礼物的最大价值
递归超时,fine。原创 2021-09-17 12:15:24 · 93 阅读 · 0 评论 -
动规&&剑指 Offer 46. 把数字翻译成字符串
直接遍历不行,只能记录两个组合状态。原创 2021-09-14 09:50:44 · 75 阅读 · 0 评论 -
自定义排序&&剑指 Offer 45. 把数组排成最小的数
未料到排序规则。排序规则为:若 x+y>y+x,则x”大于“y,反之,若x+y<y+x,则x”小于“y。 参考:剑指 Offer 45. 把数组排成最小的数(自定义排序,清晰图解)定义内置函数规则:class Solution {public: string minNumber(vector<int>& nums) { vector<string>s; string res; for(auto num:原创 2021-09-09 15:34:17 · 95 阅读 · 0 评论 -
状态机&&遍历统计&&剑指 Offer 56 - II. 数组中数字出现的次数 II
目标:在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。不能像 上一题 一样用异或分组的方法,根据数据特点来设计算法,看到了数电状态机的方法和遍历统计的方法。参考:面试题56 - II. 数组中数字出现的次数 II(位运算 + 有限状态自动机,清晰图解)1.状态机(用到了数电时序逻辑电路分析状态转移图的内容)2.遍历统计(nums在int范围内31位每一位相加,对3求余后得到所求数字,注意count数组和移位的顺序)class Solution {原创 2021-09-03 23:19:38 · 148 阅读 · 3 评论 -
位运算&&剑指 Offer 56 - I. 数组中数字出现的次数
目标:查找出两个只出现一次的数字,其他数字都出现两次。要求:时间复杂度O(n),空间复杂度O(1)。1.起始代码(这里使用了哈希表,不符合题目要求)class Solution {public: vector<int> singleNumbers(vector<int>& nums) { vector<int>ans; map<int,int>m; for(auto x:nums){原创 2021-09-03 15:25:56 · 108 阅读 · 0 评论 -
回溯&&剑指 Offer 34. 二叉树中和为某一值的路径
1.回溯法思想是对的,但起始写的回溯函数写的有问题,调试不出来: void recur(TreeNode* root, int target, vector<int>tmp, int sum) { if (root == NULL||sum>target) return; if (sum == target) { ans.push_back(tmp); } tmp.push_back(root-原创 2021-09-02 23:44:55 · 94 阅读 · 0 评论 -
递归分治&&单调栈&&剑指 Offer 33. 二叉搜索树的后序遍历序列
参考:面试题33. 二叉搜索树的后序遍历序列(递归分治 / 单调栈,清晰图解)1.递归方法划分左右区间方法:遍历寻找第一个大于根结点的点。(1)递归终止条件:左>=右;(2)递推工作:划分左右子树,判断是否为二叉搜索树;(3)返回值:分别判断树、左子树、右子树是否正确。class Solution {public: bool recur(vector<int>&postorder,int i,int j){ if(i>=j) retur原创 2021-09-01 14:28:53 · 113 阅读 · 0 评论 -
迭代+求余取整&&剑指 Offer 44. 数字序列中某一位的数字
找数学规律的题,没想到迭代法,只找到了数字规律和想到麻烦的面向测试编程,参考:面试题44. 数字序列中某一位的数字(迭代 + 求整 / 求余,清晰图解)原创 2021-08-31 22:34:06 · 115 阅读 · 0 评论 -
递归&&剑指 Offer 38. 字符串的排列
1.递归的写法有一步写错了,看了评论区老哥的答案恍然大悟,传的是 + 不是 +=class Solution {public: //递归终止条件等于字符的长度 void dfs(string s,string t,vector<bool>&visit,unordered_set<string>&list){ if(t.length()==s.length()){ list.insert(t);原创 2021-08-28 15:14:05 · 77 阅读 · 0 评论 -
剑指 Offer 36. 二叉搜索树与双向链表
参考了大佬的力扣题解:剑指 Offer 36. 二叉搜索树与双向链表(中序遍历,清晰图解)递归:(1)递归终止条件;(2)递归操作。这里二叉搜索树采用中序遍历,操作在遍历左子树和右子树中间。/*// Definition for a Node.class Node {public: int val; Node* left; Node* right; Node() {} Node(int _val) { val = _val;原创 2021-08-27 15:51:56 · 78 阅读 · 0 评论 -
哈希表&&剑指 Offer 35. 复杂链表的复制
看不懂题目可太难了,直接return head不行,先复制next再复制random也不行……遍历复制可以构建next引用指向,无法构建random引用指向。1.哈希表/*// Definition for a Node.class Node {public: int val; Node* next; Node* random; Node(int _val) { val = _val; next = NULL;原创 2021-08-27 12:50:01 · 88 阅读 · 0 评论 -
快速幂&&剑指 Offer 16. 数值的整数次方
快速幂_学习class Solution {public: //加深了对快速幂的理解和认识 double myPow(double x, int n) { if(n==0) return (double)1; double y=1; long int t=(long)n; //1.00000 -2147483648这个测试用例使得需要long x=(n>0?x:(t=-t,1/x));原创 2021-08-26 15:59:45 · 64 阅读 · 0 评论 -
判断&&剑指 Offer 20. 表示数值的字符串
虽然学习了正则表达式,但是放这题用c++正则表达式求解超时了 return regex_match(s,regex("\\s*[+-]?((\\d+)|(\\d*\\.\\d+)|(\\d+\\.\\d*))([eE][+-]?\\d+)?\\s*"));参考和学习了正则表达式的以下内容:正则表达式 - 语法正则表达式里的底层原理是什么C++正则表达式藏在正则表达式里的陷阱一个由正则表达式引发的血案关于正则表达式里含有空格的问题正则表达式测试网站...原创 2021-08-25 16:46:35 · 70 阅读 · 0 评论 -
先序+判断&&剑指 Offer 26. 树的子结构
返回值为bool类型的题目,不一定直接return true;也可能return一个判断语句。附上大佬的力扣题解先序遍历+判断/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }原创 2021-08-24 14:43:15 · 67 阅读 · 0 评论 -
dfs&&动规&&剑指 Offer 14- I. 剪绳子
1.dfs(自己按照输出瞎琢磨出来的方法,时间复杂度较高,题目的n<=58)class Solution {public: //递归 //递归终止条件:剩余绳子长度 //传递值:当前段、剩余段的大小,乘积 //递推工作:每一段从1开始尝试到末尾 int maxnum=1; void dfs(int start,int temp,int n){ if(n==1||n==0){ maxnum=max(maxnum,原创 2021-08-23 13:34:08 · 84 阅读 · 0 评论 -
dfs&&剑指 Offer 07. 重建二叉树
目的:给出前序遍历和中序遍历的结果,且不包含重复数字,求出原始二叉树。思路:二叉树前序遍历的第一个结点为根节点,依据中序遍历找到根节点,此时中序遍历根节点左边全部是左子树,右边全部是右子树。按照这么个递归分治,最终重建二叉树,不过二叉树的边界挺难看懂,想半天。。dfs:(1)递归参数;(2)递归终止条件;(3)递推工作。心得:太难了,看题解都得看半天,最后才差不多研究出那么一回事。注意:按照前序遍历理解传递的参数:根结点root,左子树的左边界left,右子树的右边界right。每次在根结点处建立新原创 2021-08-20 16:07:24 · 98 阅读 · 0 评论 -
思维&&剑指 Offer 64. 求1+2+…+n
目的:求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。力扣评论区各种秀,只想到公式,最终本质还是n(n+1)/2,看到了各种脑洞。1.分配律;return ((int)pow(n,2)+n)>>1;2.建立bool数组的二维内存空间+sizeof();3.递归的&&短路性质代替不能使用的if递归终止判断。...原创 2021-08-20 14:27:12 · 49 阅读 · 0 评论 -
dfs&&bfs&&剑指 Offer 13. 机器人的运动范围
跟 矩阵中的路径 那一题相似,有一步写错了研究了好久错误。class Solution {public: //需要做的操作:取数位和,判断,记录最大值 //递归解法 int row,col,maxnum=0,tmp=1; vector<vector<bool>> f; //标志数组 int digital(int i){ //取数位和 int count=0; while(i){原创 2021-08-18 16:46:16 · 90 阅读 · 0 评论 -
递归+剪枝&&剑指 Offer 12. 矩阵中的路径
目的:在字符矩阵中可上下左右寻找给定的字符串,返回bool。看了K神的dfs和回溯剪枝,还学习了如何使用方向数组:面试题12. 矩阵中的路径( DFS + 剪枝 ,清晰图解)class Solution {public: //dfs+剪枝 int row,col; bool dfs(vector<vector<char>>& board,string word,int i,int j,int k){ if(i<0 || i原创 2021-08-18 14:25:54 · 106 阅读 · 0 评论 -
枚举&&二分法&&剑指 Offer 04. 二维数组中的查找
目的:从每行每列都递增的二位数组中查找target。1.枚举(最简单的方法,O(n^2)时间复杂度,忽略了行列递增排序的条件2.二分法(对每一行都二分查找,O(n^logn)时间复杂度,但是忽略了列递增的条件写了半天,原来是return true的if条件需要判断边界值left和right防止溢出,二分法没写错。class Solution {public: //二分查找+遍历,将双重循环的O(n^2)时间复杂度降到O(n*logn) bool findNumberIn2DArra原创 2021-08-17 16:36:37 · 90 阅读 · 0 评论 -
中序&&递归&&剑指 Offer 68 - II. 二叉树的最近公共祖先
1.中序遍历+循环判断(结合二叉搜索树那题,自己写的代码昨天的二叉搜索树:递归&&迭代&&剑指 Offer 68 - I. 二叉搜索树的最近公共祖先依旧按照三种情况判断两个结点在左孩子、右孩子、异侧的情况,不过判断操作单独写在一个void dfs()函数里面。解答过程中,画图分析代码错误最后写出来,这个有冗余操作,每一次都要判断两个结点在哪一边(调用dfs()函数),增加了时间复杂度。/** * Definition for a binary tree node.原创 2021-08-17 14:25:57 · 100 阅读 · 0 评论 -
递归&&迭代&&剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
大佬还是那个大佬,我还是那个菜鸡。化繁为简,三种情况,(1)p,q都在左子树;(2)p,q都在右子树;(3)p,q异侧,直接返回根节点。二叉搜索树性质:左孩子的值比当前节点值小,右孩子的值比当前节点值大。参考大佬的力扣题解:面试题68 - I. 二叉搜索树的最近公共祖先(迭代 / 递归,清晰图解)1.递归/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *l原创 2021-08-16 23:46:09 · 122 阅读 · 0 评论 -
约瑟夫环问题&&动规&&剑指 Offer 62. 圆圈中最后剩下的数字
当数据规模比较大时,用链表法while(node->next->next){ }遍历删除会超时,考虑数学和动态规划解法(发现dp[n-1]和dp[n]之间的关系,即这个状态和下一个状态之间的关系,这里是数字下表的映射关系,大问题分成下一个小问题解决)。...原创 2021-08-16 22:34:28 · 64 阅读 · 0 评论 -
二叉树先序遍历&&后序遍历&&剑指 Offer 55 - II. 平衡二叉树
原来是之前做过的题目“判断二叉树深度“的拓展题:bfs&&dfs&&剑指 Offer 55 - I. 二叉树的深度返回值是bool类型时,return 的代码不一定直接写 return true or return false,也有返回一个判断和条件来让机器自己判断是否是true or false。话不多说,参考了K神的题解:面试题55 - II. 平衡二叉树(从底至顶、从顶至底,清晰图解)1.先序遍历+判断深度(感觉是从avl树的定义入手,但是有重复计算的部分a原创 2021-08-16 14:23:42 · 91 阅读 · 0 评论 -
集合&&排序&&剑指 Offer 61. 扑克牌中的顺子
扑克牌的顺子,大小王居然可以代替任何一张牌当顺子。。。没懂这个前提条件确实难以看懂这道题。起始想法,列出所有排序数组,找到满足题意的数组就返回true,还要判断大小王数量,挺复杂,直到看到大佬把列出了三种情况(即大小王的数量),得出统一的判断条件:返回true条件:max-min<5 && 无重复牌。参考了大佬的力扣题解:面试题61. 扑克牌中的顺子(集合 Set / 排序,清晰图解)1.集合class Solution {public: bool isStraig原创 2021-08-15 00:21:06 · 102 阅读 · 3 评论 -
位运算实现加法&&剑指 Offer 65. 不用加减乘除做加法
a + b = (a ^ b) ^ ((a & b)) << 1;循环至进位数为0为止。abn(无进位和)c(进位)0000011010101101参考了大佬的题解:面试题65. 不用加减乘除做加法(位运算,清晰图解)1.java提交可以过class Solution { public int add(int a, int b) { while(b!=0){ i原创 2021-08-13 16:39:29 · 70 阅读 · 0 评论 -
中序遍历&&剑指 Offer 54. 二叉搜索树的第k大节点
注意:是二叉搜索树的中序遍历是递增序列,不是二叉树,普通二叉树和搜索树的性质不一样。1.原先想的层序遍历节点值,再查找第k大的数的方法(菜鸡代码占的空间可能比较大,没注意到是搜索树orz……/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x),原创 2021-08-13 14:24:51 · 71 阅读 · 0 评论 -
二分法&&剑指 Offer 53 - II. 0~n-1中缺失的数字
K神:排序数组的查找问题,首先想到二分法。下面是自己写的二分法,不枉昨天研究了三小时,掌握了精髓。class Solution {public: int missingNumber(vector<int>& nums) { //二分查找 int left=0,right=nums.size()-1; while(left<=right){ int mid=left+((right-left)>原创 2021-08-13 12:39:46 · 64 阅读 · 0 评论 -
取余运算&&剑指 Offer 58 - II. 左旋转字符串
主要是记录一下没想到的取余运算:1.取余运算class Solution {public: string reverseLeftWords(string s, int n) { string ans=""; int length=s.length(); for(int i=0;i<length;i++){ ans+=(s[(i+n)%length]); } return ans;原创 2021-08-13 12:02:38 · 51 阅读 · 0 评论 -
二分法&&剑指 Offer 53 - I. 在排序数组中查找数字 I
目标:在非递减数组中统计一个数字出现的次数。1.遍历(O(n)时间复杂度,很容易想到的解法,不过应该不是面试考察的内容class Solution {public: int search(vector<int>& nums, int target) { //O(n)时间复杂度,直接遍历 int count=0; for(auto x:nums){ if(x==target){原创 2021-08-12 16:35:14 · 68 阅读 · 0 评论 -
双指针&&哈希&&剑指 Offer 52. 两个链表的第一个公共节点
首先想到的是vector< int >存储节点值然后比较,或者弄两次前插从尾部读取公共部分,但是太麻烦了,而且比较的貌似是内存地址,不是值,如下图这组数据:参考了力扣官方题解:两个链表的第一个公共节点1.双指针/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(原创 2021-08-12 13:20:38 · 71 阅读 · 0 评论 -
滑动窗口优化&&剑指 Offer 57 - II. 和为s的连续正数序列
1.原始写的冗长滑动窗口代码(用了queue数据结构class Solution {public: vector<vector<int>> findContinuousSequence(int target) { vector<vector<int>>ans; queue<int>q; //队列遍历到数组中点 int mid=(target+1)/2; int sum原创 2021-08-11 16:34:56 · 66 阅读 · 0 评论 -
bfs&&dfs&&剑指 Offer 55 - I. 二叉树的深度
之前看别人blog时,发现写在注释里的一句话:dfs优先考虑递归,bfs优先考虑队列。这不,今儿个就用上了。1.bfs这里队列while里面也可以创建新的临时队列,然后重新赋给原始队列。/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x),原创 2021-08-11 13:00:01 · 108 阅读 · 0 评论