学习笔记
修呀
这个作者很懒,什么都没留下…
展开
-
学习笔记43——翻转单词顺序
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。思路:一道很经典的面试题,两次翻转字符串。第一步翻转句子中所有的字符;第二步再翻转每个单词中字符的顺序。核心代码如下:void Reverse(char* pBegin, char* pEn...原创 2019-05-24 09:52:50 · 160 阅读 · 0 评论 -
学习笔记36——丑数
题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。思路:方法二根据丑数的定义,丑数应该是另一个丑数乘以2、3或5的结果(1除外),因此我们可以创建一个数组,里面的数字是排好序的丑数,每个丑数都是前面的丑数乘以2、3或5得到的。在给数组排序过程中,假设数组中已...原创 2019-05-20 11:27:46 · 259 阅读 · 0 评论 -
学习笔记35——最长不含重复子串的子字符串(两种方法)
题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符串中只包含从’a’到’z’的字符。例如,在字符串"arabcacfr"中,最长的不含重复字符的子字符串是"acfr",长度为4。思路:方法一:暴力法,时间复杂度为O(n3)一个长度为n的字符串有O(n2)个子字符串,我们找出所有的子字符串,然后需要O(n)判断每个子字符串中是否包含重复的字符,总的时间...原创 2019-05-14 15:07:25 · 479 阅读 · 0 评论 -
学习笔记33——字符串的排列(未避免重复字符和避免重复字符)
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。思路:求整个字符串的排列,可以分为两步:第一步:求所有可能出现在第一个位置的字符(即把第一个字符和后面所有的字符交换);第二步:固定第一个字符,求后面所有字符的排列(即仍把后面的所有字符分为两部分:后面字符的第一个字符,...原创 2019-05-06 20:33:01 · 262 阅读 · 0 评论 -
学习笔记32——二叉搜索树与双向链表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路:由于要求转换后的链表是排序的,而中序遍历算法的特点就是按照从小到大的顺序遍历二叉树每个节点,因此采用中序遍历树中每个节点,当遍历到根节点时,把树分为3部分:根节点、左子树和右子树,通过递归把左、右子树都转换成排序双向链表后,把左子树中最大的节点、根节点、右子树中最小的节点...原创 2019-05-06 20:04:52 · 99 阅读 · 0 评论 -
学习笔记31——复杂链表的复制(不使用辅助空间,时间复杂度为O(n)的解法)
题目:请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling 指向链表中的任意结点或者nullptr。思路:主要分为三步,具体如下第一步:复制原始链表的任意节点N并创建新节点N’,再把N’链接到N的后面;第二步:如果原始链表上的节...原创 2019-04-24 09:17:01 · 180 阅读 · 0 评论 -
学习笔记30——二叉树中和为某一值的路径
题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。思路:用前序遍历访问二叉树节点,当访问到某一节点时,把该节点添加到路径上,并累加该节点的值。1.如果该节点为叶子节点(节点访问结束),且且路径上节点值的和等于输入的整数,则打印出这条路径;2.如果当前节点不是叶子节点,则遍历它的子节点;3.如果该节点是叶子...原创 2019-04-22 22:40:40 · 80 阅读 · 0 评论 -
学习笔记29——判断某数组是不是某二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。思路:根据二叉树的性质:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。在后序遍历得到的序列中,最后一个数字是树的根节点的值。整体采用递归的思想来判别。核心代码如下:...原创 2019-04-22 21:31:35 · 137 阅读 · 0 评论 -
学习笔记28——按之字形打印二叉树
题目:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。思路:按之字形打印二叉树需要两个栈,在打印某一层的节点时,把下一层的子节点保存到相应的栈里。1.如果当前打印的是奇数层,则先保存左子节点再保存右子节点;如果当前打印的是偶数层,则先保存右子节点再保存左子节点2.在打印一个栈里的节点时,它的...原创 2019-04-22 21:03:23 · 95 阅读 · 0 评论 -
学习笔记27——分行从上到下打印二叉树
题目:从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印到一行。思路:实质是考察树的按层遍历算法,应该利用队列先入先出的特性来完成打印。每次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放到队列的末尾;接下来到队列的头部取出最早进入队列的节点,重复前面的打印操作,直到队列中所有的节点都被打印出来。为了把二叉树的每一行单独打印到一行里,需要两个变量:nextLevel...原创 2019-04-22 19:42:57 · 152 阅读 · 0 评论 -
学习笔记21——树的子结构
题目:输入两棵二叉树A和B,判断B是不是A的子结构。思路:整个过程分为两步:第一步,在树A中找到和树B的根节点的值一样的节点R;第二步,判断树A中以R为根节点的子树是不是包含和树B一样的结构。当树A或树B为空时,定义相应的输出。采用递归的思路来判断树A中以R为根节点的子树是不是和树B具有相同的结构,递归的终止条件是我们达到了树A或者树B的叶子节点。核心代码如下:struct BinaryTr...原创 2019-04-17 21:42:39 · 81 阅读 · 0 评论 -
学习笔记44——滑动窗口的最大值
题目:给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。示例:如果输入数组{2, 3, 4, 2, 6, 2, 5, 1}及滑动窗口的大小3,那么一共存在6个滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5}思路:一个滑动窗口可以看成一个队列,我们不把滑动窗口的每个值都存入队列,而是只把有可能成为滑动窗口最大值的数值存入队列。由于队列头部尾部都有可能删除数字,因此需要用...原创 2019-05-24 16:09:22 · 445 阅读 · 0 评论 -
学习笔记42——和为s的连续正数序列
题目:输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。示例:例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。思路:可以用两个数small和big分别表示序列的最小值和最大值,首先把small初始化为1,big初始化为2,然后按照以下规则操作条件操作small到big的序列和大于s从序列中...原创 2019-05-24 09:26:00 · 79 阅读 · 0 评论 -
学习笔记41——数组中只出现一次的两个数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。思路:利用异或运算的特点(任何一个数字异或它自己都等于0),如果我们从头到尾依次异或数组中的每个数字,那么最终的结果刚好是那个只出现一次的数字,因为那些成对出现两次的数字全部在异或中抵消了。因此解题过程可以分为两步:第一步——把原数组分为两个子数组,...原创 2019-05-23 20:30:10 · 160 阅读 · 0 评论 -
学习笔记40——平衡二叉树(通过后序遍历,每个节点只遍历一次)
题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左、右子树的深度相差不超过1,那么它就是一棵平衡二叉树。二叉树的深度:从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。思路:简单方法:在遍历树的每个节点的时候,通过函数计算得到它的左、右子树的深度,如果每个节点的左、右子树的深度都不超过1,那么它就是平衡二叉树。这种方法通...原创 2019-05-23 16:30:22 · 778 阅读 · 0 评论 -
学习笔记39——在排序数组中查找数字(二分查找法,时间复杂度O(logn))
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。思路:假设要统计数字k在排序数组中出现的次数,基于二分查找法直接找到第一个k和最后一个k,在分别找到第一个k和最后一个k的对应下标以后,就能计算出k在排序数组中出现的次数。核心代码如下://寻找排序数组中第一个k,如果数组中不存在k,返...原创 2019-05-22 17:20:01 · 1107 阅读 · 0 评论 -
学习笔记34——数据流中的中位数(最大堆和最小堆方法)
题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。分析:如果数据在容器中已经排序,定义两个指针P1、P2指向容器中间的节点(如果容器中节点数目是奇数,那么P1和P2指向同一个节点),此时整个数据容器被分隔成两部分,位于容器左边的数据比右边的数据小,P1指向...原创 2019-05-13 11:14:48 · 590 阅读 · 0 评论 -
学习笔记48——把字符串转换成整数
题目:请写一个函数StrToInt,实现把字符串转换成整数这个功能。当然,不能使用atoi或者其他类似的库函数。思路:除了实现基本功能,核心在于需要把所有特殊情况都考虑进去,并对这些特殊的输入都定义好合理的输出。核心代码如下:long long StrToIntCore(const char* digit, bool minus);enum Status {kValid = 0, kIn...原创 2019-05-25 20:51:59 · 252 阅读 · 0 评论 -
学习笔记47——圆圈中最后剩下的数字(用环形链表模拟约瑟夫环)
题目:0, 1, …, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。思路:可以创建一个共有n个节点的环形链表,然后每次在这个环形链表中删除第m个节点。这种方法每删除一个数字需要m步运算,共有n个数字,因此总的时间复杂度是0(m*n),同时这种思路还需要一个辅助链表来模拟圆圈,其空间复杂度是0(n)。核心代码如下:int Last...原创 2019-05-25 19:12:40 · 244 阅读 · 0 评论 -
学习笔记38——两个链表的第一个公共节点(三种思路)
题目:输入两个链表,找出它们的第一个公共结点。假设第一个链表长度为m,第二个链表长度为n。思路1:时间复杂度O(mn)在第一个链表上顺序遍历每个节点,每遍历到一个节点,就在第二个链表上顺序遍历每个节点。如果在第二个链表上有一个节点和第一个链表上的节点一样,则说明两个链表在这个节点上重合,于是就找到了它们的公共节点。思路2:时间复杂度O(m+n),空间复杂度O(m+n)如果两个链表有公共节...原创 2019-05-22 09:34:16 · 166 阅读 · 0 评论 -
学习笔记46——扑克牌中的顺子
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字。思路:第一步——将数组排序,调用排序函数qsort。第二步——统计数组中0的个数numberOfZero(0为大、小王)。第三步——统计排序之后数组中相邻数字之间的空缺总数numberOfGap,如果numberOfGap >...原创 2019-05-25 16:53:54 · 312 阅读 · 0 评论 -
学习笔记45——n个骰子的点数(递归法,时间效率较低)
题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。思路:第一步——先统计出每个点数出现的次数先把那个骰子分为两堆:第一堆只有一个;另一堆有n-1个。需要计算单独那个骰子有可能出现1~6的点数和剩下的n-1个骰子来计算点数和。接下来把剩下的n-1个骰子仍然分成两堆:第一堆只有一个;另一堆有n-1个。递归进行下去。第二步——把每个点数出现的次数...原创 2019-05-25 16:04:07 · 401 阅读 · 0 评论 -
学习笔记26——判断序列是否为栈的弹出序列
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。思路:在判断过程中,如果下一个弹出的数字刚好是栈顶数字,那么直接弹出;如果下一个数字不在栈顶,则把压栈序列pNextPush中...原创 2019-04-22 16:38:41 · 373 阅读 · 0 评论 -
学习笔记25——包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。思路:新建一个辅助栈,每次压入一个新元素进数据栈时,都把此时的最小元素压入辅助栈,那么就能保证辅助栈的栈顶一直都是最小元素。当元素从数据栈内被弹出以后,同时弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值。核心代码如下:template &...原创 2019-04-22 15:44:55 · 87 阅读 · 0 评论 -
学习笔记24——顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。思路:把矩阵看成由若干个顺时针方向的圆组成,用一个循环来打印矩阵,每次打印矩阵中的一个圆。循环继续的条件为columns > startX * 2 并且 rows > startY * 2(令每一圈的左上角为(startY,startX))。接着把打印一圈分为四步:第一步,从左到右打印一行;第二步,从上到下打印一列;...原创 2019-04-22 11:09:03 · 75 阅读 · 0 评论 -
学习笔记10——用两个队列实现一个栈
题目:用两个队列实现一个栈。栈的声明如下,同学习笔记9类似。请实现它的两个函数appendTail和deleteHead,分别完成在栈中压入一个结点和弹出一个节点的功能。思路:同笔记9类似,可通过画图形象化理解。元素压入的时候,保持一个队列为空,一个队列不为空,往不为空的队列中插入元素;弹出一个元素e时,从非空队列q1(或q2,后同)入手,将e之前的元素统统插入队列q2并在q1中删除它们,然后删...原创 2019-03-31 22:08:28 · 99 阅读 · 0 评论 -
学习笔记3——不修改数组找出重复的数字(空间复杂度为O(1))
在一个长度为n+1的数组里的所有数字都在1~n的范围内。所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。具体代码如下:#include <iostream>using namespace std;int countRange(const...原创 2019-03-24 11:08:13 · 445 阅读 · 0 评论 -
学习笔记2——找出数组中重复的数字(时间复杂度为O(n),空间复杂度为O(1))
在一个长度为n的数组里的左右数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次,请找出数组中任意一个重复的数字。原创 2019-03-23 23:07:23 · 2241 阅读 · 1 评论 -
学习笔记1——赋值运算符函数
当定义一个赋值运算符函数时,应注意以下四点:为了使运算符能够进行连续赋值,应把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身的引用(*this)。是否把传入的参数的类型声明为常量引用。因为如果传入的参数是实例的话,从形参到实参会调用一次复制构造函数,把参数声明为引用可以避免此种情况。为了防止内存泄漏,应在分配新内存之前释放实例自身已有的内存。事先判断传入的参数和当前的实例(*...原创 2019-03-23 16:26:06 · 342 阅读 · 0 评论 -
学习笔记9——用两个栈实现队列
题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。思路:当stack2不为空时,在stack2中的栈顶元素是最先进入队列的元素,可以弹出;在插入一个元素时,直接将元素插入到stack1中。核心代码如下:template <typename T> //队列声明class...原创 2019-03-26 16:52:58 · 96 阅读 · 0 评论 -
学习笔记8——找出中序遍历序列二叉树的下一个节点
题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。思路:在中序遍历序列中,如果一个节点有右子树,那么它的下一个节点就是它的右子树中的最左节点;如果一个节点没有右子树,如果节点是它父节点的右子节点,则沿着指向父节点的指针一直向上遍历,直到找到一个是它父节点的左子节点的节点,如果这样的节点存在,那么这...原创 2019-03-26 15:08:37 · 489 阅读 · 0 评论 -
学习笔记7——重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6},则重建出二叉树并输出它的头结点。思路: 容易知道,前序遍历序列中的第一个数字就是根节点的值,然后根据这个数字在中序遍历序列中找到根节点的位置,从而确...原创 2019-03-26 11:03:51 · 149 阅读 · 0 评论 -
学习笔记6——从尾到头打印链表
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。思路:在不改变链表的结构的情况下,可以用栈实现这种顺序,首先遍历链表,每经过一个节点时,把该节点放入栈中,当遍历完整个链表后,再从栈顶开始逐个输出节点的值,即典型的“后进先出”。核心代码如下:struct ListNode{ int m_nKey; ListNode* m_pNext;};//迭代方法实现void Pr...原创 2019-03-26 09:13:25 · 132 阅读 · 0 评论 -
学习笔记5——替换空格(时间复杂度为O(n))
题目:请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入“We are happy.”,则输出“We%20are%20happy.”。思路:采用从后向前替换。先遍历一遍字符串,统计字符串中空格数,则替换后字符串的总长度 = 原长度+2*空格数;然后准备两个指针,indexOfOrigin指向原始字符串的末尾,indexOfNew指向替换后字符串的末尾,开始向前移动执行替换操作,直到两...原创 2019-03-25 11:22:40 · 333 阅读 · 0 评论 -
学习笔记4——二维数组中的查找
**题目:**在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。**思路:**从二维数组的右上角数字作为突破口开始分析(也可以是左下角,但不能是左上角数字或者右下角数字),与查找数字进行比较,比较过程如下表:当前数字 == 要查找数字查找过程结束,found = tru...原创 2019-03-25 10:30:03 · 114 阅读 · 0 评论 -
学习笔记11——旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组 {3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。思路:利用二分查找法,用两个指针index1和index2分别指向数组的第一个元素和最后一个元素,接着找到数组中间的元素indexMid,如果index1值小于中...原创 2019-04-01 11:26:04 · 95 阅读 · 0 评论 -
学习笔记12——剪绳子
*题目:给你一根长度为n绳子,请把绳子剪成m段(m、n都是整数,n>1并且m≥1)。每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1]…k[m]可能的最大乘积是多少?例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。思路:可以用动态规划和贪婪算法解决此类寻找最优解的问题。动态规划:时间复杂度O(nn),空间复杂度O(n)。要从...原创 2019-04-02 09:31:45 · 228 阅读 · 0 评论 -
学习笔记23——对称的二叉树
题目:请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。思路:定义一种对称前序遍历算法,即先遍历父节点,再遍历它的右子节点,最后遍历它的左子节点。最后通过比较二叉树的前序遍历序列和对称前序遍历序列来判断二叉树是否对称,如果两个序列是一样的,那么二叉树就是对称的。核心代码如下:struct BinaryTreeNode{ double m_nVal...原创 2019-04-22 10:10:24 · 123 阅读 · 0 评论 -
学习笔记22——二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。思路:先前序遍历这课二叉树的每个节点,如果遍历到的节点有子节点,就交换它的两个子节点。当交换完所有非叶节点的左、右子节点之后,就得到了树的镜像。分别有递归和迭代两种解法,推荐递归解法。核心代码如下:struct BinaryTreeNode{ double m_nValue; BinaryTreeNode* m_pLeft; B...原创 2019-04-22 09:36:18 · 83 阅读 · 0 评论 -
学习笔记20——合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。思路:首先判断两个链表是否为空,然后利用递归完成合并过程。核心代码如下:struct ListNode{ int m_nKey; ListNode* m_pNext;};ListNode* Merge(ListNode* pHead1, ListNode* pHead2){ if(pHead1 =...原创 2019-04-17 10:48:01 · 134 阅读 · 0 评论