![](https://img-blog.csdnimg.cn/20190918140037908.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
剑指offer(第二版)
剑指offer(C++版)
吃着火锅x唱着歌
这个作者很懒,什么都没留下…
展开
-
剑指offer 学习笔记 把字符串转换成整数
面试题67:把字符串转换成整数。类似atoi,把一个字符串转换成一个整数。原创 2020-08-17 15:47:59 · 122 阅读 · 0 评论 -
剑指offer 学习笔记 数据流中的中位数
面试题41:数据流中的中位数。如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值;如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。由于数据是从...原创 2020-08-16 19:14:56 · 95 阅读 · 0 评论 -
剑指offer 学习笔记 包含min函数的栈
面试题30:包含min函数的栈。定义栈的数据结构,在该类型中实现一个能够得到栈的最小元素的min函数,该栈中,调用min、push、pop的时间复杂度都是O(1)。可以创建一个辅助栈。分析:第一次压入3时,将3也压入辅助栈,之后再压入4时,由于4大于3,继续往辅助栈中压入3,即辅助栈中元素数量永远与栈中元素数量相同,但辅助栈中与栈对应的位置的值永远是该位置到栈底所有元素中最小的元素值。当弹出元素时,将辅助栈的栈顶元素也弹出。...原创 2020-05-12 16:44:03 · 128 阅读 · 0 评论 -
剑指offer 学习笔记 用两个栈实现队列
面试题9:用两个栈实现队列。原创 2020-05-11 19:23:23 · 93 阅读 · 0 评论 -
剑指offer 学习笔记 赋值运算符函数
面试题1:赋值运算符函数。如下为类型CMyString的声明,为该类型添加赋值运算符函数。class CMyString {public: CMyString(char *pData = nullptr); CMyString(const CMyString &str); ~CMyString(void);private: char *m_pData...原创 2020-05-08 16:01:44 · 142 阅读 · 0 评论 -
剑指offer 学习笔记 树中两个节点的最低公共祖先
面试题68:树中两个节点的最低公共祖先。可以先得到从根节点到这两个节点的路径,之后找出最后一个公共节点,代码中的树为:#include <iostream>using namespace std;struct TreeNode { int m_nValue; vector<TreeNode*> m_chlidren;};bool GetNo...原创 2020-04-27 13:54:40 · 122 阅读 · 0 评论 -
剑指offer 学习笔记 构建乘积数组
面试题66:构建乘积数组。给定一个数组A[n],请构建一个数组B[n],其中B[i]=A[0]xA[1]x…xA[i-1]xA[i+1]x…xA[n-1],不能使用除法。如没有不能使用除法的限制,可以用A中所有元素的乘积除A[i]来得到B[i],此时要注意A[i]=0的情况。法一:连乘n-1个数字获得B[i],时间复杂度为O(n²),太慢了。法二:B[i]可以看做两个连续的子数组的乘积,我们...原创 2020-04-26 07:13:45 · 117 阅读 · 0 评论 -
剑指offer 学习笔记 不用加减乘除做加法
面试题65:不用加减乘除做加法。原创 2020-04-24 18:07:47 · 122 阅读 · 0 评论 -
剑指offer 学习笔记 求1+2+...+n
面试题64:求1+2+…+n。不能用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(包括A?B:C)。法一:构造函数求解。循环让相同的代码循环运行n次,我们也可以不用循环语句完成,先定义一个类型,接着创建n个该类型的对象,那么这个类型的构造函数就会被调用n次:#include <iostream>using namespace std;...原创 2020-04-23 11:54:46 · 219 阅读 · 0 评论 -
剑指offer 学习笔记 股票的最大利润
面试题63:假设把某股票的价格按照时间先后顺序存储在数组中,买卖该股票一次可能获得的最大利润是多少?如输入{9,11,8,5,7,12,16,14},则我们在价格为5时买入,在价格为16时卖出可以获得最大利润11。最简单的就是蛮力法,找出数组中所有数对,求出它们的差值,找出最大差值,由于数组中有O(n²)个数对,因此该算法时间复杂度为O(n²)。另一种思路,当我们卖出价为下标为i的价格时,可能...原创 2020-04-19 14:35:28 · 100 阅读 · 0 评论 -
剑指offer 学习笔记 圆圈中最后剩下的数字
面试题62:圆圈中最后剩下的数字。0、1、…、n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。本题就是约瑟夫环问题。法一:用环形链表模拟圆圈,我们可以直接用标准库的list模拟环形链表,但标准库的list不是环形的,但我们可以在迭代器扫描到链表末尾时将该迭代器移动到链表头部,以此来模拟环形链表:#include <iostr...原创 2020-04-18 17:52:38 · 186 阅读 · 0 评论 -
剑指offer 学习笔记 扑克牌中的顺子
面试题61:扑克牌中的顺子。从扑克牌中随机抽5张牌,判断是不是一个顺子,A为1,J为11,Q为12,K为13,大小王可以看做任何数字。可以把5张牌看成由5个数字组成的数组,大小王为特殊数字,可以将它俩定义为0。之后判断这5个数字是否是连续的,最简单的方法就是将数组排序,如果排序后的数组不是连续的,即两个数字间隔若干个数字,此时只要我们有足够的0可以补满这两个数字间的空缺,那么该数组还是连续的。因...原创 2020-04-16 14:11:36 · 177 阅读 · 1 评论 -
剑指offer 学习笔记 n个骰子的点数
面试题60:n个骰子的点数。把n个骰子扔在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能的值出现的概率。原创 2020-04-15 20:08:33 · 143 阅读 · 0 评论 -
剑指offer 学习笔记 翻转字符串
面试题58:翻转字符串。1.输入一个英文句子,翻转句子中的单词顺序,但单词内字符的顺序不变,标点看做普通字符。如,输入"I am a student.",输出"student. a am I"。第一步我们翻转整个句子,如上例,反转后结果为".tneduts a ma I",第二步翻转每个单词的顺序即可:#include <iostream>#include <string...原创 2020-04-13 18:09:49 · 149 阅读 · 1 评论 -
剑指offer 学习笔记 和为s的数字
面试题57:和为s的数字。1.输入一个递增的数组和一个数字s,在数组中查找两个数,使它们的和正好是s,输出一对这样的数即可。即使是不好的直观解法,想到后也要告诉面试官,这样显得思维敏捷,如一种时间复杂度为O(n²)的解法,固定数组中的一个数字,然后依次判断数组中其余n-1个数字与它的和是否为s。我们可以令两个指针分别指向数组中的首元素和尾元素,然后把这两个元素相加,如果和大于s,那么将后边的...原创 2020-04-10 13:24:42 · 97 阅读 · 0 评论 -
剑指offer 学习笔记 数组中数字出现的次数
面试题56:数组中数字出现的次数。1.一个整型数组里除两个数字之外,其他数字都出现了两次,找出这两个只出现一次的数字,要求时间复杂度O(n),空间复杂度O(1)。先分析如果只有一个数字出现一次,而其他数字都出现了两次,我们就可以依次异或数组中的每个数字,由于异或运算满足交换律,因此只要异或序列中有两个相同的数字就可以将这两个数字都变为0,而0与任何数字异或都是这个数字自己,这样最后的异或结果就...原创 2020-04-07 13:13:58 · 212 阅读 · 0 评论 -
剑指offer 学习笔记 二叉树的深度
面试题55:二叉树的深度。1.输入一棵二叉树,求该树的深度。只需遍历整棵树的每一条路径找出最长的即可,以下代码中的树结构为:#include <iostream>using namespace std;struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeN...原创 2020-04-05 17:03:02 · 94 阅读 · 0 评论 -
剑指offer 学习笔记 二叉搜索树的第K大节点
面试题54:二叉搜索树的第K大节点。给定一棵二叉搜索树,找出其中第K大的节点。中序遍历到第K个元素即可:#include <iostream>using namespace std;struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRigh...原创 2020-04-03 13:50:26 · 131 阅读 · 0 评论 -
剑指offer 学习笔记 在排序数组中查找数字
面试题53:在排序数组中查找数字。1.统计一个数字在排序数组中出现的次数。解法:在排序数组中使用二分查找算法,直到找到第一个指定数字,之后遍历这个数字的左右两边,直到遍历到非这个数字的值,就可以得到出现次数。但要查找的数字可能在长为n的数组中出现O(n)次,时间复杂度是O(n),太慢了。改进的解法:我们花费大量时间在确定数字第一次出现的位置和最后一次出现的位置,我们可以直接使用二分查找算法得...原创 2020-04-02 15:18:38 · 144 阅读 · 0 评论 -
剑指offer 学习笔记 两个链表的第一个公共节点
面试题52:两个链表的第一个公共节点。输入两个链表,找出它们的第一个公共节点,链表节点定义如下:struct ListNode { int m_nKey; ListNode* m_pNext;};蛮力法:在第一个链表上顺序遍历每个节点,每遍历到一个节点,就在第二个链表上顺序遍历每个节点,直到找到第一个公共节点,如果第一个链表长为m,第二个链表长度为n,那么时间复杂度为O(m...原创 2020-03-30 15:09:53 · 115 阅读 · 0 评论 -
剑指offer 学习笔记 数组中的逆序对
面试题51:数组中的逆序对。在数组中的任意两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。如数组{7,5,6,4}中,一共存在5个逆序对。直观解法是顺序扫描整个数组,每扫描到一个数字,逐个比较该数字和它后面的数字的大小,如果后面的数字比它小,则这两个数字组成一个逆序对。这种算法的时间复杂度是O(n²),太慢了。当我们每扫描到一个...原创 2020-03-29 19:51:16 · 141 阅读 · 0 评论 -
剑指offer 学习笔记 第一个只出现一次的字符
面试题50:第一个只出现一次的字符。1.在字符串中找到第一个只出现一次的字符。如输入"abaccdeff",则输出’b’。最直观想法是从头开始扫描整个字符串,每当访问到一个字符时,拿这个字符和后面每个比较,如果在后面没有重复的字符,则这个字符就是只出现一次的字符,如果字符串有n个字符,则时间复杂度为O(n²),太慢了。题目与字符出现的次数有关,我们可以统计每个字符在该串中出现的次数,为实现它...原创 2020-03-26 15:09:50 · 177 阅读 · 0 评论 -
剑指offer 学习笔记 丑数
面试题49:丑数。我们把只包含因子2、3、5的数称为丑数。求按从小到大的顺序的第1500个丑数。如6、8是丑数,但14不是,因为14包含因子7,习惯上我们把1当做第一个丑数。根据丑数定义,丑数只能被2、3、5整除,即,如一个数能被2(3或5)整除,就连续除以2(3或5),如果最后得到的是1,那么这个数就是丑数,否则不是:bool isUgly(int num) { while (num...原创 2020-03-24 23:43:26 · 88 阅读 · 0 评论 -
剑指offer 学习笔记 最长不含重复字符的子字符串
面试题48:最长不含重复字符的子字符串。请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符只包含’a’~'z’的字符。如在字符串"arabcacfr"中,最长的不含重复字符的子字符串是"acfr",长度为4。我们不难找出字符串的所有子字符串,然后判断每个子字符串中是否包含重复的字符,这种蛮力法的唯一缺点就是效率,一个长为n的字符串中有O(n²)个子字符串,并且...原创 2020-03-23 19:42:54 · 125 阅读 · 1 评论 -
剑指offer 学习笔记 礼物的最大价值
面试题47:礼物的最大价值。在一个mxn的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格,直到到达棋盘的右下角。给定一个棋盘和上面的礼物,请计算你最多能拿到多少价值的礼物。这是一个典型的能用动态规划解决的问题,先用递归思路来分析,我们先定义第一个函数f(i,j)表示到达坐标为(i,j)的格子时能拿到的礼物总和的...原创 2020-03-22 13:50:54 · 216 阅读 · 0 评论 -
剑指offer 学习笔记 把数字翻译成字符串
面试题46:把数字翻译成字符串。给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成“a”,1翻译成“b”,…,25翻译成“z”。一个数字可能有多个翻译,如,12258有5种不同翻译,分别是“bccfi”、“bwfi”、“bczi”、“mcfi”和“mzi”,编程实现一个函数,计算一个数字有多少种不同的翻译方法。我们以12258为例分析,我们有两种选择来翻译第一位数字1,第一种是翻译为“b”...原创 2020-03-21 15:04:08 · 107 阅读 · 0 评论 -
剑指offer 学习笔记 把数组排成最小的数
面试题45:把数组排成最小的数。输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。如,输入{3,32,321},则打印出这三个数字能排出的最小数字321323。这道题最简单的解法是先求出数组中所有数字的全排列,然后把每个排列都拼起来,最后求出拼起来的数字的最小值,n个数字总共有n!个排列,效率低。我们需要找到一个排序规则,数组根据这个排序规则能排成一个...原创 2020-03-20 11:52:13 · 112 阅读 · 0 评论 -
剑指offer 学习笔记 数字序列中某一位的数字
面试题44:数字序列中某一位数字。数字以0123456789121112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。最直观的方法就是从0开始枚举每个数字,枚举到一个数字时,求出该数字的位数,并把位数和前面所有数字的位数相加,如果位数之和仍然小于等于n,则继续枚举下一个数字,当累加的位...原创 2020-03-18 16:56:30 · 122 阅读 · 0 评论 -
剑指offer 学习笔记 1~n整数中1出现的次数
面试题43:1~\n整数中1出现的次数。输入一个整数,求1~n这n个整数的十进制表示中1出现的次数。解法一:最直观的解法,累加1~n中每个1出现的次数,我们可以对10求余数判断整数的个位数字是不是1。如果这个数字大于10,在判断次低位时需要将数字除以10之后再判断除10后结果的个位数是不是1:#include <iostream>using namespace std;int...原创 2020-03-16 16:21:31 · 138 阅读 · 0 评论 -
剑指offer 学习笔记 连续子数组的最大和
面试题42:连续子数组的最大和。输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求子数组中数字的和的最大值,要求时间复杂度为O(n)。直观解法是枚举数组中所有子数组并求出它们的和。一个长度为n的数组,总共有n(n+1)/2个子数组,计算出所有子数组的和,最快也要O(n²)。解法一:我们试着从头到尾逐个累加数组中的每个数字。和初始化为0。例如输入数组为{1,-2...原创 2020-03-15 14:04:04 · 119 阅读 · 0 评论 -
剑指offer 学习笔记 最小的k个数
面试题40:最小的k个数。输入n个数,找出其中最小的k个数。最简单的方法就是排序数组,找出前k个数即可。这种思路时间复杂度为O(nlogn),太慢了,以下方法时间复杂度为O(n)。此方法只有当我们可以修改输入数组时才能使用,基于快排的Partition函数,找到一轮排序后下标为k-1的数字,这个数组的前k项即为最小的k个数,但不一定是有序的:#include <iostream>...原创 2020-03-14 11:38:45 · 103 阅读 · 0 评论 -
剑指offer 学习笔记 数组中出现次数超过一半的数字
C/C++中我们要养成使用指针或引用传递复杂类型参数的习惯,如采用值传递,则从实参到形参会产生一次复制操作。对同一算法用递归和循环的时间效率可能也不会一样,递归的本质是将一个大的复杂问题分解成两个或多个小的简单问题,如果小问题中有相互重叠的部分,那么直接使用递归实现虽然代码会比较简洁,但时间效率可能会很差,对于这种问题,我们可以用递归的思路来分析问题,但写代码时候可以用数组来保存中间结果从而基于...原创 2020-03-13 13:14:22 · 125 阅读 · 0 评论 -
剑指offer 学习笔记 字符串的排列
面试题38:字符串的排列。输入一个字符串,打印出该字符串中字符的所有排列。如输入abc,则输出六个不同的全排列。我们可以把求排列的过程分为两步,第一步求可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换;第二步固定一个字符,求后面所有字符的排列,后面字符的排列的求解过程又与以上步骤相同,这就可以使用递归来完成整个解题步骤:#include <iostream>#inc...原创 2020-03-12 17:24:29 · 84 阅读 · 0 评论 -
剑指offer 学习笔记 序列化二叉树
面试题37:序列化二叉树。实现两个函数,分别用来序列化和反序列化。我们可以先把一棵二叉树序列化成一个前序遍历序列和一个中序遍历序列,然后在反序列化时通过这两个序列重构出二叉树。但该思路有两个缺点:一是该方法要求二叉树中没有值重复的节点;二是只有当两个序列中所有数据都读出后才能开始反序列化,如果两个遍历序列的数据是从一个流中读出来的,那么可能需要等待较长时间。实际上,如果二叉树的序列化是从根节点...原创 2020-03-10 13:26:52 · 105 阅读 · 0 评论 -
剑指offer 学习笔记 二叉搜索树与双向链表
面试题36:二叉搜索树与双向链表。输入一棵二叉搜索树,将该二叉树转换成一个排序的双向链表。要求不能创建任何新节点,只能调整树中节点指针的指向。二叉树中,每个节点都有两个指向子节点的指针,双向链表中,每个节点也有两个指针,分别指向前一个节点和后一个节点。在二叉搜索树中,所有左子节点的值总是小于父节点的值,所有右子节点的值总是大于父节点的值,且左右子树都是一棵二叉搜索树,因此,我们在将二叉搜索树转换...原创 2020-03-09 17:11:48 · 113 阅读 · 0 评论 -
剑指offer 学习笔记 复杂链表的复制
分治法:把分解后的小问题各个解决,然后把小问题的解决方案结合起来解决大问题。面试题35:复杂链表的复制。请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,每个节点除了有一个m_pNext指针指向下一个节点,还有一个m_pSibling指针指向链表中任意节点或者nullptr。节点定义如下:struct Com...原创 2020-03-08 14:49:47 · 92 阅读 · 0 评论 -
剑指offer 学习笔记 二叉树中和为某一值的路径
面试题34:二叉树中和为某一值的路径。输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始,往下一直到叶节点所经过的节点形成一条路径。二叉树节点定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight;};...原创 2020-03-07 13:22:43 · 94 阅读 · 0 评论 -
剑指offer 学习笔记 二叉搜索树的后序遍历序列
面试题33:二叉搜索树的后序遍历序列。输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果(只要存在一个二叉搜索树的后序遍历结果为它即可)。如果是返回true,不是返回false。假设输入数组的任意两个数字都不相同。后序遍历得到的序列中,最后一个数字是树的根节点的值。数组中前面的数字可分为两部分,第一部分是左子树的值,它们都比根节点小,第二部分是右子树的值,它们都比根节点大。我们接下来...原创 2020-03-06 11:41:30 · 115 阅读 · 0 评论 -
剑指offer 学习笔记 从上到下打印二叉树
面试题32:从上到下打印二叉树。(1)从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。以上图为例,按层打印先打印根节点8,之后把第二层的6、10保存在队列中,现在队列中有两个节点,按从左到右的打印要求,我们先取出值为6的节点打印,之后把它的节点5、7入队列,然后出队列的值是10,出队列后,将10的两个节点9、11入队列,现在第三层也是从左到右的顺序入队列了。我们不用再定义...原创 2020-03-05 11:47:27 · 135 阅读 · 0 评论 -
剑指offer 学习笔记 栈的压入、弹出序列
面试题31:栈的压入、弹出序列。输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。解决这个问题很直观的想法是建立一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从栈中弹出数字。判断方法:如果下一个要弹出的数字刚好等于栈顶数字,那么直接弹出。如果下一个要弹出的数字不等于栈顶数字,那么把压栈序列的数字...原创 2020-03-04 13:20:31 · 120 阅读 · 0 评论