![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
剑指offer
YTea
这个作者很懒,什么都没留下…
展开
-
【剑指】70.涉及自定义类
ListNode.h:#pragma oncestruct ListNode{ int val; ListNode* next; ListNode(int value) : val(value), next(nullptr) {} ListNode() {}};ListNode* CreateListNode(int value);void Conn...原创 2018-08-08 14:07:31 · 125 阅读 · 0 评论 -
【剑指】58(2).左旋转字符串
题目描述字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab"。算法分析分两段各做一次翻转,再做一次总的翻转。提交代码:class Solution {public: string LeftRotateString(string st...原创 2018-07-18 19:17:14 · 126 阅读 · 0 评论 -
【剑指】59(1).滑动窗口的最大值
题目描述给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,如果输入数组{2, 3, 4, 2, 6, 2, 5, 1}及滑动窗口的大小3,那么一共存在6个滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5}。算法分析用一个双端队列,队列第一个位置保存当前窗口的最大值,当窗口滑动一次判断当前最大值是否过期;新增加的值从队尾开始比较,把所有比他小的值丢掉。...原创 2018-07-19 09:41:55 · 95 阅读 · 0 评论 -
【剑指】29.顺时针打印矩阵
题目描述输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。算法分析矩阵的顺时针圈数取决于列和行较小的一个; 圈循环时存在边角点的从属问题,若边角点作为下一次循环中的第一个数,考虑到各种情况,代码处理会比较复杂,因此将边角点作为上一次循环中的最后一个数输出; 当矩阵为单行及单列时候,会出现重复输出的情况(从上到下后,又从下到上输出;从左到右后,又从右到左输出),因此需...原创 2018-07-06 14:49:02 · 93 阅读 · 0 评论 -
【剑指】59(2).队列的最大值
题目描述请定义一个队列并实现函数max得到队列里的最大值,要求函数max、push_back和pop_front的时间复杂度都是O(1)。算法分析使用一个双向的队列来保存滑动窗口中的值,使最大值总是在双向队列的头部,新的元素和对尾的元素比较,如果队尾的元素小于新的元素,就把队尾的元素删除,然后从队尾加入新的元素;但是怎么判断在队列头的最大值是否过期呢,那么这就需要在双向队列中...原创 2018-07-19 09:42:31 · 328 阅读 · 0 评论 -
【剑指】30.包含min函数的栈
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。算法分析使用两个栈,一个栈用来存储数据,另一个栈用来存储对应数据的最小值;提交代码:class Solution {public: void push(int value) { if (minVal.empty() || value < mi...原创 2018-07-06 15:40:16 · 102 阅读 · 0 评论 -
【剑指】31.栈的压入、弹出序列
题目描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。算法分析借用一个辅助的栈,遍历压栈顺序,先将第一个元素压入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,...原创 2018-07-06 16:44:40 · 99 阅读 · 0 评论 -
【剑指】32(1).不分行从上往下打印二叉树
题目描述不分行从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。算法分析广度优先遍历搜索问题,用一个队列保存将要搜索的这一层的元素,然后逐个搜索:1. 将第一个元素加入队列;2. 队列不为空时取队首元素;3. 将下一层元素加入队尾;4. 回到第二步,直到队列为空。提交代码:class Solution {public: vector<int> PrintFromT...原创 2018-07-06 17:52:20 · 97 阅读 · 0 评论 -
【剑指】32(2).分行从上到下打印二叉树
题目描述从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印到一行。算法分析与32(1)基本相同,但需要考虑元素所处层的问题;原本使用了两个队列,其中一个用来保存元素所属的层数,经过修改发现可以不需要使用这个队列,节省了空间。提交代码:class Solution {public: vector<vector<int> > Print(TreeNode*...原创 2018-07-06 18:53:57 · 132 阅读 · 0 评论 -
【剑指】58(1).翻转单词顺序
题目描述输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student.",则输出"student. a am I"。算法分析先翻转整个句子,然后,依次翻转每个单词。依据空格来确定单词的起始和终止位置提交代码:class Solution {public: string ReverseSen...原创 2018-07-18 16:33:53 · 116 阅读 · 0 评论 -
【剑指】50(2).字符流中第一个只出现一次的字符
题目描述请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是'g'。当从该字符流中读出前六个字符"google"时,第一个只出现一次的字符是'l'。如果当前字符流没有存在出现一次的字符,返回#字符。算法分析建立一个256个大小的int型数组来代表哈希表,存储字母出现的位置,-1代表未出现,-2代表已经重复出现,>=0代表...原创 2018-07-12 15:39:58 · 136 阅读 · 0 评论 -
【剑指】47.礼物的最大价值
题目描述在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?算法分析动态规划,申请一个与原矩阵行列数一样的二维数组dp,然后依次更新dp的每一行即可。由于第m行的值与第m-1行和第m行有关,因此可以对dp进行简化,仅用一维...原创 2018-07-12 12:30:49 · 198 阅读 · 0 评论 -
【剑指】48.最长不含重复字符的子字符串
题目描述请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符串中只包含从'a'到'z'的字符。算法分析动态规划,创建一个26大小的一维数组,用来存储上一次出现某个字符的索引。我们分情况讨论:设到第i个字符的最长不重复子字符串长度为f(i)(1)如果第i个字符之前没有出现过。f(i) = f(i-1)+1;(2)如果第i个字符之前出现过,又分两种情况: ...原创 2018-07-12 13:17:56 · 124 阅读 · 0 评论 -
【剑指】49.丑数
题目描述把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。算法分析法一:逐个判断每个整数是不是丑数。根据丑数的定义,丑数只能被2,3,5整除,也就是说,如果一个数能被2整除,连续除以2,如果能被3整除,连续除以3,如果能被5整除,连续除以5,如果最后得到1,那么这个数就...原创 2018-07-12 14:21:21 · 210 阅读 · 0 评论 -
【剑指】50(1).字符串中第一个只出现一次的字符
题目描述在一个字符串(0<=字符串长度<=10000, 全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回-1。算法分析用哈希表记录每个字符出现的个数,第一遍扫描这个string时,每碰到一个字符,在哈希表中找到对应的项并把出现的次数增加一次。第二次扫描时,返回第一个哈希表中记录次数为1的字符的位置。提交代码:class Solution {public:...原创 2018-07-12 14:45:15 · 108 阅读 · 0 评论 -
【剑指】26.树的子结构
题目描述输入两棵二叉树A和B,判断B是不是A的子结构。算法分析两次递归,首先需要递归A树,找到与B根一样的节点,这需要一个遍历;找到相同的根节点后,要判断是否子树,仍需要一个一个遍历对比。提交代码:class Solution {public: bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) { if (!pRoot1 || !pR...原创 2018-07-05 19:41:28 · 163 阅读 · 0 评论 -
【剑指】27.二叉树的镜像
题目描述操作给定的二叉树,将其变换为源二叉树的镜像。算法分析递归法:依次遍历二叉树每个节点,并调换其左右子树;迭代法:(1)深度优先法,使用栈实现,优先调换左/右子树的结点,然后调换另一子树的结点;(2)广度优先法,使用队列实现,优先调换同深度的结点,然后调换子树结点。提交代码:class Solution {public: /* 递归法 */ void Mirror1(TreeNode *...原创 2018-07-05 20:47:17 · 158 阅读 · 0 评论 -
【剑指】28.对称的二叉树
题目描述请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。算法分析递归,左子树和右子树对比,右子树和左子树对比;提交代码(原始代码):class Solution {public: bool isSymmetrical(TreeNode* pRoot) { if (!pRoot) return true; return isSy...原创 2018-07-05 21:20:18 · 121 阅读 · 0 评论 -
【剑指】57(2).为s的连续正数序列
题目描述输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。算法分析初始化small=1,big=2; small到big序列和小于sum,big++; 大于sum,small++; 当small增加到(1+sum)/2是停止提交代码:class ...原创 2018-07-18 14:23:44 · 112 阅读 · 0 评论 -
【剑指】32(3).之字形打印二叉树
题目描述请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。算法分析设两个栈s1和s2,s1存放奇数层,s2存放偶数层;遍历s1节点的同时按照左子树、右子树的顺序加入s2,遍历s2节点的同时按照右子树、左子树的顺序加入s1。提交代码:class Solution {public: vector&l...原创 2018-07-06 20:09:17 · 116 阅读 · 0 评论 -
【剑指】56(2).数组中唯一只出现一次的数字
题目描述在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。请找出那个吃出现一次的数字。算法分析我们把数组中所有数字的二进制表示的每一位都加起来。如果某一位的和能被3整除,那么那个只出现一次的数字二进制表示中对应的那一位是0;否则就是1。这种解法的时间效率是O(n)。我们需要一个长度为32的辅助数组存储二进制表示的每一位的和。由于数组的长度是固定的,因此空间效率是O(1)。提...原创 2018-07-18 12:10:54 · 149 阅读 · 0 评论 -
【剑指】62.圆圈中最后剩下的数字
题目描述0, 1, …, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。算法分析方法一:使用链表来模拟圆圈,时间复杂度为O(mn),空间复杂度O(n)。方法二:约瑟夫环问题的数学公式法求解,公式推导见约瑟夫环问题 ( 最简单的数学解法),得到公式f(n, m)= [f(n-1, m) + m] % n,其中,m表示...原创 2018-08-07 15:30:55 · 108 阅读 · 0 评论 -
【剑指】63.股票的最大利润
题目描述假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖交易该股票可能获得的利润是多少?例如一只股票在某些时间节点的价格为{9, 11, 8, 5, 7, 12, 16, 14}。如果我们能在价格为5的时候买入并在价格为16时卖出,则能收获最大的利润11。算法分析遍历数组,扫描到数组中的第i个数字时,保存之前的i-1个数字中的最小值,以及利润最大值,就能算出当前价位卖出时...原创 2018-08-07 15:40:55 · 157 阅读 · 0 评论 -
【剑指】64.求1+2+…+n
题目描述求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。算法分析利用逻辑与的短路特性实现递归终止;当n==0时,(n>0)&&((sum+=Sum_Solution(n-1))>0)只执行前面的判断,为false,然后直接返回0;当n>0时,执行sum+=Sum...原创 2018-08-07 15:51:42 · 79 阅读 · 0 评论 -
【剑指】65.不用加减乘除做加法
题目描述写一个函数,求两个整数之和,要求在函数体内不得使用+、-、×、÷ 四则运算符号。算法分析1. 两个数异或:相当于每一位相加,而不考虑进位;2. 两个数相与,并左移一位:相当于求得进位;2. 将上述两步的结果相加,即重复1,2。提交代码:class Solution {public: int Add(int num1, int num2) { in...原创 2018-08-07 16:16:07 · 98 阅读 · 0 评论 -
【剑指】66.构建乘积数组
题目描述给定一个数组A[0, 1, …, n-1],请构建一个数组B[0, 1, …, n-1],其中B中的元素B[i] =A[0]×A[1]×… ×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。算法分析B[i]的值可以看作下图的矩阵中每行的乘积。下三角用连乘可以很容求得,上三角,从下向上也是连乘。因此,先计算下三角中的连乘,即我们先算出B[i]中的一部分,然后...原创 2018-08-07 16:56:56 · 125 阅读 · 0 评论 -
【剑指】67.把字符串转换成整数
题目描述请你写一个函数StrToInt,实现把字符串转换成整数这个功能。当然,不能使用atoi或者其他类似的库函数。算法分析考虑边界条件,数据上下溢出、空字符串、只有正负号、有无正负号、错误标志输出等;0值和无效输入之间的区分加个标志位即可,由于牛客网没有对该项做要求,加之作者偷懒,就没写了。提交代码:class Solution {public: int Str...原创 2018-08-07 18:30:03 · 118 阅读 · 0 评论 -
【剑指】68.树中两个结点的最低公共祖先
题目描述输入两个二叉树结点,求它们的最低公共祖先。算法分析用两个链表分别保存从根节点到输入的两个节点的路径,然后把问题转换成两个链表的最后公共节点。提交代码:class Solution {public: const TreeNode* getLastCommonParent(const TreeNode* pRoot, const TreeNode* pN...原创 2018-08-08 13:36:10 · 80 阅读 · 0 评论 -
【剑指】69.矩阵覆盖
题目描述我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?算法分析斐波那契数列问题,f(1) = 1, f(2) = 2, f(3) = f(1) + f(2), ..., f(n) = f(n-2) + f(n-1), ...提交代码:class Solution {public: i...原创 2018-08-08 14:02:07 · 102 阅读 · 0 评论 -
【剑指】61.扑克牌的顺子
题目描述从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字,认为大小王是0。算法分析首先把数组排序,再统计数组中0的个数,最后统计排序之后的数组中相邻数字之间的空缺总数。如果空缺的总数小于或者等于0的个数,那么这个数组就是连续的:反之则不连续。 最后,还需要注意,如果数组中的非0...原创 2018-07-19 21:56:38 · 120 阅读 · 0 评论 -
【剑指】60.n个骰子的点数
题目描述把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。算法分析思路一:基于递归求骰子点数,时间效率不够高。先把骰子分成两堆,第一堆只有一个,第二堆有n-1个, 单独的那一个可能出现1到6的点数,我们需要计算从1-6的每一种点数和剩下的n-1个骰子来计算点数和。 还是把n-1个那部分分成两堆,上一轮的单独骰子点数和这一轮的...原创 2018-07-19 21:10:52 · 192 阅读 · 0 评论 -
【剑指】33.二叉搜索树的后序遍历序列
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。算法分析递归法:BST的后序序列的合法序列是,对于一个序列S,最后一个元素是x (也就是根),如果去掉最后一个元素的序列为T,那么T满足:T可以分成两段,前一段(左子树)小于x,后一段(右子树)大于x,且这两段(子树)都是合法的后序序列。迭代法:...原创 2018-07-07 14:32:46 · 121 阅读 · 0 评论 -
【剑指】51.数组中的逆序对
题目描述在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007算法分析先把数组分割成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。在统计逆序对的过程中,还需要对数组进行排序。如果对排序算法很熟悉,我们不难发现这...原创 2018-07-13 16:11:05 · 92 阅读 · 0 评论 -
【剑指】34.二叉树中和为某一值的路径
题目描述输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。算法分析递归先序遍历树, 把结点加入路径;若该结点是叶子结点,则比较当前路径和是否等于期待和;每次递归返回时,当前路径也应该回退一个结点;加入了对当前路径和的判断,而不是遍历到叶子节点才判断路径和,减少了递归调用;提交代码:class Solution {pu...原创 2018-07-07 16:19:42 · 88 阅读 · 0 评论 -
【剑指】35.复杂链表的复制
题目描述请实现函数RandomListNode* Clone(RandomListNode* pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个next指针指向下一个结点外,还有一个random 指向链表中的任意结点或者nullptr。算法分析三步法(图源见水印)哈希表法:首先遍历原链表,创建新链表(赋值label和next),用哈希表关联对应结点;再遍历一原链表,更新新链表的ran...原创 2018-07-07 17:24:01 · 143 阅读 · 0 评论 -
【剑指】52.两个链表的第一个公共结点
题目描述输入两个链表,找出它们的第一个公共结点。算法分析找出2个链表的长度,然后让长的先走两个链表的长度差,然后再一起走(因为2个链表用公共的尾部)。提交代码:class Solution {public: ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) { if (!pHead1 || !pHead2)...原创 2018-07-13 18:20:21 · 108 阅读 · 0 评论 -
【剑指】53(1).数字在排序数组中出现的次数
题目描述统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。算法分析对有序数组进行折半查找,找出数字第一个出现的位置和最后一个出现的位置,求出出现的次数。提交代码:class Solution {public: int GetNumberOfK(vector<int> data, i...原创 2018-07-13 19:33:09 · 108 阅读 · 0 评论 -
【剑指】53(2).0到n-1中缺失的数字
题目描述一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0到n-1之内。在范围0到n-1的n个数字中有且只有一个数字不在该数组中,请找出这个数字。算法分析若数组没有缺失,则每个数字和它的下标都相等。然而,现在数组有缺失,说明从缺失的那个数开始,后面的数字都比它的下标大1。因此找出第一个数值和下标不相等的数,那么,它的下标就是缺失的那个数。 数组可看成两部分,前半段数值和下...原创 2018-07-13 20:16:03 · 196 阅读 · 0 评论 -
【剑指】54.二叉搜索树的第k个结点
题目描述给定一棵二叉搜索树,请找出其中的第k大的结点。算法分析二叉搜索树按照中序遍历的顺序打印出来正好就是排序好的顺序。 所以,按照中序遍历顺序找到第k个结点就是结果。提交代码:class Solution {public: TreeNode* KthNode(TreeNode* pRoot, int k) { if (!pRoot || k <= 0) return nul...原创 2018-07-13 21:01:27 · 91 阅读 · 0 评论 -
【剑指】57(1).和为s的两个数字
题目描述输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。算法分析数列满足递增,设两个头尾两个指针i和j, 若ai + aj == sum,就是答案(相差越远乘积越小) 若ai + aj > sum,aj肯定不是答案之一(前面已得出 i 前面的数已是不可能),j -= 1 若ai ...原创 2018-07-18 13:14:02 · 91 阅读 · 0 评论