- 博客(56)
- 资源 (1)
- 收藏
- 关注
原创 剑指offer-66
构建乘积数组,给定一个数组A[0,1,2,3,…,N-1],构建一个数组B[0,1,…,n-1],其中b中的元素B[i]=A[0]*A[1]*…*A[i-1]*A[i+1]*…*A[N-1],不能使用除法解法一:直观地连乘,但是每次都要遍历一次,有重复运算,复杂度O(N^2)解法二:每次分为两部分,乘完左侧,再乘右侧void BuildProductionArray(const vec...
2020-01-09 18:48:51 130
原创 剑指offer-65
不用加减乘除做加法,写一个函数,在函数体内不得使用四则运算符号实现加法所有参与运算的都是以补码形式进行的 结果也是补码 因此也需要将补码转换成为原码的形式存在,正数的补码为本身,负数的补码为取反加1,补码+补码就是正负数加减加法A^b=c,a&b=d,d=d<<1, If c&d>0 继续进位Else return c^d至于为负数情况...
2020-01-09 17:41:54 140
原创 剑指offer-64
1+2+3+4+。。。+n=?,不需使用四则运算和关键字,条件判断语句解法一:用位运算模拟加法?用递归模拟循环?还是要用关键字,不符合要求A^b=c,a&b=d,d=d<<1,If c&d>0 继续进位Else return c^d解法一:不符合要求unsigned int addPos(unsigned int a, unsigned i...
2020-01-09 17:06:22 200
原创 剑指offer-62
圆圈中最后剩下的数字,0,1,2.。。,n-1这n个数字排成一圈,从数字0开始,每次从这个圆圈里删除第M个数字,求出这个圆圈里剩下的最后一个数字Eg。0,1,2,3,4,5,每次删除第3个数字,删除的前四个数字是2,0,4,1解法一:所有的节点用一个链表或者数组组合起来,模拟操作,直至会后解法二:公式推导解法一:int LastRemaining_Solution3(unsig...
2020-01-09 16:16:04 244
原创 剑指offer-63
股票最大利润,给定一个按照时间排序的价格,算出何时开始买进,何时卖出时利润最大用数组解法一:依次遍历每个时间点,再与剩下的值计算差值,寻求最大值,O(n^2)解法二:因为每次的利润只和前面的数字有关,遍历到某节点,记录前面的最小值,记录当前最大利润,进行比较厚修改前段最小值和最大利润值,遍历结束时可得 o(n)解法二:int MaxDiff(const int* numbers...
2020-01-08 20:45:31 153
原创 剑指offer-61
扑克牌中的顺子扑克牌随机抽五张,判断是不是一个顺子,2~10为数字本身,A为1,j为11,q位12,k为13,大小王可以作为任意的数字(不考虑两端情况,即k与a不连续)解法一:因为扑克牌类型大小是固定的,不区分花色的话只有14种,其中13种为A-k,大小王为1种,可以先用个大小为14的数组存储每个对应数字出现的次数,0为大小王,除王外,如果某个数字出现1次以上,则不连续;其次判断数组的数字...
2020-01-08 19:30:27 155
原创 剑指offer-60
把n个骰子置于地上,所有骰子朝上一面的点数之和为S,输入N,打印出所有可能值出现的规律每个骰子6种可能,n个骰子有6^n个结果,结果分为n~6n,统计每种结果出现的次数,即可算出概率解法一:用递归,每次递归分成两组,直至最后一个骰子,次数+1,直至算出所有结果,可能会栈溢出,效率低下解法二:通过骰子数递增来解决,如果是1个骰子会有1-6种情况,2个骰子有2-12种情况,3个骰子。。。记...
2020-01-08 17:39:33 182
原创 剑指offer-59
队列的最大值59.1 滑动窗口的最大值解法一:用一个vector队列来记录最大值每次vector传入一个值,如果该值大于队头(当前最大值),队列清空,传入值;如果该值小于对头,大于队尾,剔除队尾,直至大于当前值时,弹入该值每次最大值即队头,注意窗口大于和等于组长度的情况解法二:用两个栈模拟一个队列操作,用一个栈记录栈最大值,一个变量max记录总最大值。栈A模拟进入,栈B模拟...
2020-01-07 19:29:42 570
原创 剑指offer-58
翻转字符串58.1 翻转单词顺序,输入一个句子,翻转单词的顺序,但不能翻转单词内部的顺序用两个指针于句子两头,分别交换,直至指针相遇,再从头遍历,交换每个单词内部字母序,O(logn)void ReverseSentence(char *pData){ if (pData == nullptr) return; int len = strlen(pData); if (len...
2020-01-07 17:51:04 234
原创 剑指offer-57
和为S的数字57.1输入一个递增数组和一个数字S,在数组中找两个数字使其和为S,如果有多对数字,输出一对即可解法一:蛮力法,逐次累加解法二:利用递增特点,从两边试探加起,如果两数字和大于S,右侧往左移动,如果两数字小于S,左侧往右移,直至找到一对数bool FindNumbersWithSum(int data[], int length, int sum,int* num1, ...
2020-01-04 17:36:00 157
原创 剑指offer-56
数组中数字出现的个数56.1数组中只出现一次的两个数字,一个整形数组里除了两个数字外,其余都出现了两次,找出这两个数字,要求时间复杂度O(N),空间复杂度o(1)解法一:hash散列表存储每个出现数字的次数,遍历整个数组,时间满足,空间不满足解法二:依次遍历所有数字,查看余下数字有没有重复,时间不满足解法三:利用异或法则,两对两对出现,有一对数字不同,所有数字依次异或后,成对的被消...
2020-01-04 10:18:12 388
原创 剑指offer-55
二叉树的深度55.1 求一二叉树的深度解法一:用递归法遍历树的每一条路径,用一引用变量记录所下的层次数,每次到一个叶节点进行一次比较解法二:用一个队列进行广度优先遍历,直至叶节点,位置一个全局的层数解法三:因为单纯是计算树的深度,一棵树某一点的深度,无非是左子树+1或右子树+1解法一void TreeDepthCore(const BinaryTreeNode* pRoot...
2020-01-03 00:19:16 86
原创 剑指offer-54
给定一棵二叉搜索树,找出第K大节点啊,又要中序遍历了,左中右,写个循环实现的吧const BinaryTreeNode* KthNode(const BinaryTreeNode* pRoot, unsigned int k) //diy{ if (pRoot == nullptr || k <= 0) return nullptr; const BinaryTreeNod...
2020-01-03 00:02:03 101
原创 剑指offer-53
53.1数字x在排序数组中出现的次数解法一:遍历数组到X,开始计数,O(N)解法二:递归使用二分法遍历计数,直至当前分段上下节点出现目标数字K时开始计数解法三:二分法先查找数字k,再从k开始,往上往下计数 O(logn)解法四:找出最左一个k和最右一个K,计数 O(logn)解法三:int GetNumberOfK_Kth(const int* data, int leng...
2020-01-02 17:47:51 227
原创 剑指offer-52
两个链表的第一个公共节点两个链表有一个公共节点,最终会重合到一个链表上解法一:先用连个指针分别遍历到结尾,如果有共同结尾,就有共同节点 O(2N)先用链表尾与一种一个链表头连接,形成闭环,再用P1、P2两个指针,一个走一步,一个走两步,直至重合到节点P3,该节点一定是闭环中的一个节点O(N)以p2点作为开头,再计算该闭环有m个节点O(N)从另一个表头开始遍历,P1和p2指针相差...
2019-12-31 22:23:36 284 1
原创 剑指offer-51
数组中的逆序对解法一:暴力解法,依次遍历每个值,再计算余下数字与其形成逆序的次数解法二:仿照归并法。暴力解法在判断某个时,会多次遍历余下节点,仿照归并排序,每次分解依次,在合并的过程中进行计数,从两组待归并的最后一位开始合并,因为已经是排序好的,归并中对前面的数字就不必再比较而直接计算,还是要有图说明比较好解法一int InversePairs(int* data, int len...
2019-12-29 21:28:02 153
原创 剑指offer-50
50.1字符串中第一个只出现一次的字符,只出现一次的,而且是第一个解法一:暴力算法,遍历所有字符,再从头统计当前字符的个数O(N^2)解法二:解法一基础上,用空间换时间,用hashmap存储出现的次数,当然如果是有限个字符256,可以直接用数组,如果当前字符统计过一次,就跳过,再遍历下一字符,如此往复,某个字符走到最后一个字符且从未被统计过,则返回该数扩展:如果不止256个字符,如汉子...
2019-12-28 12:22:04 168
原创 剑指offer-49
丑数只包含因子2,3,5的数为丑数,求从小到大第N个丑数解法一:暴力算法,依次递增遍历每个数,判断该数是否为丑数,直至丑数累加至第N个,每个丑数可以通过2,3,5除尽则为丑数解法二:空间换时间,依次计算每一个丑数,非丑数不计算,直至第N个。第m个丑数,一定是前m-1个丑数中一个乘2 3 或5得到,用三个数组存,可避免重复遍历解法二可再空间优化,把三个数组缩小到一个数组,观察三个数组...
2019-12-28 10:51:44 77
原创 剑指offer-48
最长不含重复字符的子字符串,从一个字符串中找出一个最长的不包含重复字符的子字符串,计算该最长字符串的长度,字符只包含‘a’-‘z’解法一:暴力解法,依次遍历每个字符,遍历到X位,检查以X位为起点的字符串字符数,用26位数组或hashmap记录字符个数,一旦个数大于1即停止,循环到X-1位,直至结束,O(N^2)解法二:动态规划,如果以最后一个节点结束的最长子数组解法二:int ...
2019-12-27 21:17:13 150
原创 剑指offer-47
礼物的最大值,给定一个M*N的棋盘,每个棋盘里有一个标的价值的礼物,从左上角开始,每次只能向下或向右获得礼物,不能回走,直到右下角输出,求最多能拿多少礼物解法一:一般走路可以回溯法,但是该走的路必须走完,否则不知道最大值,用递归遍历所有路径解法二:动态规划,找最优子结构,申请一临时数组存储到点i最大的值,如果要输出路径可以顺带保存路径。优化空间,因为每个空间只与i-1行和j-1列格子有关,i...
2019-12-27 18:23:23 125
原创 剑指offer-46
把数字翻译成字符串,0-25对应26个字母,临接的数字可以组成多少种翻译Eg. 12258 1.2.2.5.8 12.2.5.8 12.25.8 1.22.5.8 1.2.25.8等解法一:把数字打上不同的间隔点,检查每种间隔点,能够翻译就加一,不能翻译就pass,对于N个数字,有N-1个位置可以打点,从中抽取1,2,3,4,5,。。。,n-1个点,即取组合,时间复杂度O(2^n),可怕呢...
2019-12-27 15:42:49 269
原创 剑指offer-45
把数组排成最小的数输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印拼接所有数字中最小的一个解法一:暴力解法,由前往后,逐个与后面数字替换,递归地把所有数字全排列,比较每种数字的大小,O(n^2),比较方法可以将所有数字转变成一个int进行比较,但是无法应对极大数字情况,也可以用个char数组把所有数字存储进入,遍历比较大小,因为每个拼接后的数字都是长度相等的解法二:最前的位...
2019-12-26 18:05:30 267
原创 剑指offer-44
数字序列的某一数字数字按照012345678910111213141516171819…存储,从0开始,第5位为5,第13位为1,第19位为4,求任意位置N对应的数字是多少解法一:暴力解法,由0开始遍历数字,每个数字拆开,每拆一次位数加1,直至位数等于N,即可可到对应的数字,但是会有重复拆解的情况,效率低下解法二:寻找序列特征,设立台阶推算出来,0位为0,一位数为1-9,共9个,占...
2019-12-26 10:12:09 183 1
原创 剑指offer-43
输入整数N,求1~n这N个十进制数中1出现的次数解法一:粗暴遍历,再计算每个数字包含1的个数,总数累加,O(n),有些数字没有必要走,比如22~30不可能出现1解法二:N变成数组,观察各个位数的特点,递归地拆分最高位和低位两部分,计算1出现的情况,反应不够快的话,就背吧解法一:int getNumOf1(int n)//diy{ int numof1 = 0; while (...
2019-12-25 15:04:04 195
原创 剑指offer-42
连续子数组的最大和给一个整型数组,数组有正有负,一个或连续多个整数为一个子数组,求所有子数组中数组和最大是多少(那个子数组可否求出?),时间复杂度为O(N)方法一:数组特征,从第一位开始往后累加,比较每次累加后的最大值并记录,直至累加和小于等于0时(该部分已无增长能力,也就是说从前一个开始节点到当前节点的累加和,不比当前节点开始的大),下一位重起累加,操作同上,直至结束方法二:动态规划...
2019-12-24 16:51:15 342
原创 剑指offer-41
数据流中的中位数,奇数个数字时就是排序后的中间数字,偶数个数字时就是排序后中间两个数的平均值解法一:堆的使用,策略是空间换时间最小堆和最大堆实现,奇数时放入最大堆,即中位数的左侧,偶数时放入最小堆的右侧,即中位数的右侧再放入最大堆前,先与最小堆top比较大小,取出小的放入最大堆,反之亦然获取中位数时,如果当前堆size和为偶数,取两堆top的平均数,如果为奇数,取最小堆的top...
2019-12-23 20:41:00 161
原创 剑指offer-40
最小的K个数,输入N个数,找出最小的K个数解法一:先排序再数数O(NlogN)解法二:用最大堆来保存数据,直至遍历完毕,解法三:用快速排序法找出第K位位置,K位左侧既是最小的K个数解法一:void quickSort(int* input,int len, int start, int end){ if (start < 0 || end < 0 || star...
2019-12-22 22:58:23 114
原创 剑指offer-39
数组中出现次数超过一半的数字解法一:用hashmap存储数字,遍历所有的数字并统计,如果出现超过一半个数的数字则返回,空间O(N),时间O(N)解法二:如果某数超过一半,排序后该数范围肯定覆盖了中位数,只需要找到中位数是多少即得解,注意,得到中位数后要检查是否超过半数解法三:如果数组有有一个数字超过一半,意味着这个数字出现的次数超过其他数字,两个变量,一个存储当前数字,另一个存储次...
2019-12-20 20:17:32 189
原创 剑指offer-38
输入一个字符串,打印该字符串中字符的所有排列解法一:递归得遍历所有位数,每一位替换所有数值(备用的不算,用数组tag记录数字被使用情况),用list记录要打印的结果,空间复杂度O(N),时间复杂度O(N^N),不划算解法二:分为两组,当前位和剩下位,用当前位于剩下的位数一一进行替换,可避免重复,即可导出全排列,空间O(1),时间O(N^2)解法1void Permutati...
2019-12-19 21:57:59 310 1
原创 剑指offer-37
实现序列化和反序列化二叉树的函数(1)序列化二叉树:就是采用前序遍历二叉树输出节点,再碰到左子节点或者右子节点为None的时候输出一个特殊字符“#”前序遍历并打印,遇空节点也要打印一次,就得到前序序列化(2)反序列化二叉树:根据某种遍历顺序得到的序列化字符串,重构二叉树依次往后遍历序列,根据前序遍历顺序递归地生成节点,每次生成节点遇到”$”返回bool ReadStream(i...
2019-12-19 14:51:57 152
原创 剑指offer-36
36二叉搜索树变成排序的双向链表,不能创建任何节点,只能调整树中节点指针的指向,输出最左节点二叉搜索树特征,排序的,双向链表左子树最右节点最大,右子树最左节点最小,与根链接起来注意边界条件,但凡能回环的就算结束可以由下往上先拆分,再合并,也可以由上往下先合并,再拆分void ConvertNode(BinaryTreeNode* pNode)//diy{ Binary...
2019-12-18 23:58:13 159
原创 剑指offer-35
复杂链表的复制链表节点有value,pnext和pside,pnext链接主链表,pnext可能指向任意一个链表节点,包括自己解法1:先把主链复制出来,复制的过程中,复制链节点的side指向原链节点,同时用哈希表记录原链节点和复制节点的映射关系其次,遍历复制链,用复制节点的side找原节点的side,再把原节点side的哈希映射复制给复制节点的side需要额外的存储空间O(n)...
2019-12-18 18:05:05 128
原创 剑指offer-34
给定二叉树和一个整数,打印所有路径和为输入整数的路径,路径是根节点到叶节点算一条路径用回溯法遍历所有路径,每到一个节累加该节点值如果累计值等于对应整数,则直接打印如果累计值大于,则回退如果累计值小于,继续往下直至结束如果节点中有负值,就要遍历所有的节点;如果都为正数,可以回溯void FindPath_1(BinaryTreeNode* pNode, int expe...
2019-12-17 17:20:07 154
原创 剑指offer-32
32.1不分行从上到下打印二叉树用个队列就可以32.2分行打印二叉树用队列遍历二叉树,用一个变量记录当前层的节点数,用另一个变量记录下一层节点数32.3之字形打印二叉树用两个栈来实现,一个栈记录当前遍历层,另一个栈记录下一个遍历层任意一个栈按照左->右子树方向压栈,每取出一个父节点,其子节点按照右->左子树压到另一个栈,循环往复,就能实现之字形,动手画一画...
2019-12-16 17:55:44 140
原创 剑指offer-33
判断一个数组值是否是某二叉搜索树的后序遍历序列,假设输入数组的任意两个数字互不相同二叉搜索树,左子小于等于父,右子大于父后序遍历为左右中,先左子树,再右子树,最后根节点,所以序列最后一个必为根以根为条件,把部分数字段氛围左右部分,左部分小于等于根,右部分大于根,如果右部分有小于等于根的情况,就返回错误否则分别对两个数组递归地运用以上策略进行判断bool VerifySquen...
2019-12-16 17:32:30 71
原创 剑指offer_31
栈的压入、弹出序列输入两个序列,第一序列是压入序列,第二序列是弹出序列,判断第二序列是否可能是正确的弹出序列通过一个辅助栈依次验证进出序列,写几个测试例子自己看看bool IsPopOrder(const int* pPush, const int* pPop, int nLength)//diy{ if (pPush == nullptr || pPop == nullptr ...
2019-12-15 17:59:32 68
原创 剑指offer_30
包含min函数的栈定义栈的数据结构,在该类型中实现一个能够得到栈最小元素的min函数,min,push,pop复杂度为o(1)用一个栈来作为存储栈,另外一个栈压入上一个最小值 画图看看 注意模板类的写法周全的考虑还应该有size的判断,template <typename T> class StackMin{public:...
2019-12-14 17:43:35 94
原创 剑指offer-29
顺时针打印矩阵,由外向里顺时针打印画图分析功能两部分,一部分是打印字符,根据行列值打印,存储数据可以为二维数组也可以是一维数组二部分是值位置的变化,顺时针:右->下->左->上->右->下->左->上->。。。方法一:每走一次要么少一行,要么少一列向右到底,开始增一行;向下到底,结束列减一列;向左到底,结束行减一行;向上到...
2019-12-13 21:00:32 173
原创 剑指offer-28
判断一二叉树是否是对称的既然对称,左右子树的结构应该相等,从根节点隔开,递归地判断左右子树是否相等,左树的左子等于右树的右子,左树的右子等于右树的左子,如果有不相等就返回错误递归检测空节点也是对称节点哦bool isSymmetrical(BinaryTreeNode* pRoot)//自写{ if (pRoot == nullptr) return true; ret...
2019-12-13 17:42:39 149
原创 剑指offer-27
二叉树的镜像,输入一颗二叉树,输出它的镜像用队列进行广度遍历,每到一个节点,调换左右子树位置即可void MirrorRecursively(BinaryTreeNode *pNode)//自写{ if (pNode == nullptr) return; BinaryTreeNode* pTemp = pNode->m_pLeft; pNode->m_pLeft =...
2019-12-13 15:53:56 119
ThinkingC++
2010-03-13
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人