剑指Offer
文章平均质量分 73
JarvisKao
这个作者很懒,什么都没留下…
展开
-
剑指Offer_面试题03_二维数组中的查找
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。原创 2017-07-10 19:59:10 · 347 阅读 · 0 评论 -
剑指Offer_面试题32_从1到n整数中1出现的次数(预留未解决)
题目描述求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。原创 2017-08-16 13:49:49 · 313 阅读 · 0 评论 -
剑指Offer_面试题30_最小的k个数
题目描述输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。分析:最直接的思路是排序,排序之后位于最前面的k个数即为所求;思路一:受到上一题的启发,利用快排一次分区,排到第k个数,则前面k个数就是最小的k个数。思路二:快排会更改数组,且不适合海量数据。犹记得那年数据结构老师曾提到过,海量数据找最小k个数可以维原创 2017-08-15 16:21:18 · 310 阅读 · 0 评论 -
剑指Offer_面试题29_数组中出现次数超过一半的数字
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。分析:思路一,如果是排序的数组那就好了。快排一次可以确定一个位置的数字,在他的左侧都比他小,右侧都比他大。一个数组中数字超过数组长度一半,经过排序之后,中间的位置一定是这原创 2017-08-15 16:03:43 · 292 阅读 · 0 评论 -
剑指Offer_面试题24_二叉搜索树的后序遍历序列
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。分析:二叉搜索树即二叉排序树,根节点左子树小于根,右子树大于根。以往和二叉树有关的题目都是设计前序、中序,或者中序后序,或者中序层序,因为要还原二叉树中序不可获取。但是二叉搜索树是比较特殊,因为其本身的性质,会导致后序、前序、中序有规原创 2017-08-07 13:09:44 · 379 阅读 · 0 评论 -
剑指Offer_面试题23_从上到下打印二叉树(层序遍历)
题目描述从上往下打印出二叉树的每个节点,同层节点从左至右打印。这个明显就是层序遍历二叉树,需要借助队列实现,之前在剑指 offer_面试题6_重建二叉树 中已经写了3种二叉树的遍历算法,其中层序遍历使用了双端队列deque和数组模拟队列两种方法,本次采用数组循环队列法,当是复习数据结构吧。这里约定:队头指针 front 指向队头元素,队尾指针 rear 指向队尾元素的下一个位置原创 2017-08-04 17:24:45 · 407 阅读 · 0 评论 -
剑指Offer_面试题22_栈的压入弹出序列
题目描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)分析:以前在做数据结构的题目时,判断是不是出栈序列是手动模拟入栈出栈的。那么其实写原创 2017-08-04 16:28:23 · 337 阅读 · 0 评论 -
剑指Offer_面试题17_合并两个有序链表
题目描述输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。分析:这道题有点类似于面试题4_替换空格中的扩展题目:两个有序数组合并。大体思路上是一致的,代码很类似,分别遍历两个链表,将小的结点链接到新链表表尾。后期处理有点区别就是,合并数组在循环结束后,需要用while把剩余的一个数组中的元素一次加入新数组。而本题只需要用if判断哪个链表不空然后原创 2017-07-27 12:36:48 · 401 阅读 · 0 评论 -
剑指Offer_面试题15_链表中倒数第k个结点
题目描述输入一个链表,输出该链表中倒数第k个结点。最后一个结点时倒数第一分析:一般思路是先遍历出链表长度,然后在移动指针到指定位置。如果面试官要求只遍历一次,那么就需要两个指针,让第一个指针先走k-1步,然后第二个指针开始从头走,直到第一个指针指到链表尾。由于两个指针始终保持k-1距离,那么当第一个指针指向表尾倒数第一,那么第二个指针指向倒数第k。注意:1.空表;2.k越界;3.k原创 2017-07-27 10:52:41 · 289 阅读 · 0 评论 -
剑指Offer_面试题33_把数组排成最小的数
题目描述输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。分析:本质上其实是一种排序思想。数组中的两个元素m,n, 如果mn > nm 那么就认定m > n, 只要按照这个规则进行升序排序,然后将排序后的数组元素按顺序组合即可。相当于一个元素“小”,那么他尽量排原创 2017-08-17 21:05:36 · 350 阅读 · 0 评论 -
剑指Offer_面试题31_连续子数组的最大和
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。例:{1,-2, 3, 10,-4, 7, 2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为18。分析:枚举出所有可能肯定不行,因为时间复杂度最快也是O(n^2),通常这种最直观的方法也不是最优解,面试官不会喜欢的。原创 2017-09-04 13:41:41 · 354 阅读 · 0 评论 -
剑指Offer_面试题41_和为s的两个数字 VS 和为s的连续正数序列
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得他们的和正好是s。分析:这个问题首先能想到用穷举的方法穷举出所有2个数字的组合判断是否符合条件。有这个想法其实可以说出来,证明你反应快,maybe。 然后对于排序数组而言其实可以使用双指针的方法,一个低位一个高位,从指向第一个和最后一个数字开始,如果和小于s,低位指针++,如果和大于s,高位指针--,直到遍历完全。我个人觉得其原创 2017-09-05 15:07:21 · 371 阅读 · 0 评论 -
剑指Offer_面试题40_数组中只出现一次的数字
题目描述一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。分析:如果让我来解的话,我首先想到的尽可能效率高的方法是用hash表,便利一遍,得到结果;解法一:unordered_map, first用来保存数组int内容,second 用来统计数字,遍历之后,遍历以便unordered_map,其中second项等于1的即为所求class原创 2017-09-05 13:57:48 · 374 阅读 · 0 评论 -
剑指Offer_面试题39_二叉树的深度 & 判断平衡二叉树
题目描述输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。分析:先序遍历二叉树节点从根开始,每遍历一个节点深度+1,到达叶子节点获得当前叶子深度,判断与max的大小进行更新。回退一次深度-1。总结就是在线序遍历的基础上增加当前深度和最大深度两个参数(引用或者指针),遍历到叶子结点进行比较max。/*st原创 2017-09-05 10:38:37 · 273 阅读 · 0 评论 -
剑指Offer_面试题38_数字在排序数组中出现的次数
题目描述统计一个数字在排序数组中出现的次数。分析:遍历一遍数组可以得到结果,时间复杂度O(n),但是这完全没利用排序数组的特性。提到排序数组查找问题就想到二分查找,二分查找O( logn )找到k,但这个k的位置是不确定的,不知道是第几个k,如果能用两次二分查找找到第一个k和最后一个k,就能得到k的个数,并且时间复杂度是O(logN);非递归:class Solution {原创 2017-09-04 21:36:15 · 299 阅读 · 0 评论 -
剑指Offer_面试题37_两个链表的第一个公共结点
题目描述输入两个链表,找出它们的第一个公共结点。解法一:允许使用辅助空间,利用哈希表std::unordered_set/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {public:原创 2017-09-04 20:14:59 · 305 阅读 · 0 评论 -
剑指Offer_面试题36_数组中的逆序对
题目描述在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007输入描述:题目保证输入的数组中没有的相同的数字数据范围: 对于%50的数据,size 对于%75的数据,size 对于%100的数据,size示例1输入原创 2017-09-04 17:09:38 · 291 阅读 · 0 评论 -
剑指Offer_面试题35_第一个只出现一次的字符
题目描述在一个字符串(1分析:用数组模拟哈希表,没毛病class Solution {public: int FirstNotRepeatingChar(string str) { int record[256] = {0}; int res = -1; for(char c : str) ++rec原创 2017-09-04 15:08:54 · 282 阅读 · 0 评论 -
剑指Offer_面试题34_丑数
题目描述把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。分析:逐个判断每个数是不是丑数,这种方法效率太低。可以用空间换时间,保存前面的丑数,根据丑数规则计算,三个指针p2 p3 p5class Solution {public: int Get原创 2017-09-04 15:01:57 · 525 阅读 · 0 评论 -
剑指Offer_面试题21_包含min函数的栈
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1)。分析:数组模拟栈可以做到O(1)push和pop,但是只有一个数组的话min还是O(n)级。那么只能在push的时候就记录最小值,但是万一最小值出栈,此时的最小值该怎么办?难道要记录次小值?那次小值在哪,难道还要记录次小值下标········原创 2017-08-04 14:48:20 · 288 阅读 · 0 评论 -
剑指Offer_面试题20_顺时针打印矩阵
题目描述输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 89 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.分析:这种题目看起来很抽象,需要动手画图找规律。顺时针打印其实可以分解成从原创 2017-08-04 10:53:42 · 348 阅读 · 0 评论 -
剑指Offer_面试题11_数值的整数次方
题目:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。不能用库函数,同时不需要考虑大数问题。分析:实现特定库函数的功能是常见的一类面试题,要求我们熟练使用库函数同时理解实现原理。千万不要直接上来就for循环相乘输出,而忘了考虑exponent为0为负整数的情况。解法一:分治递归民工解法。负指数次幂 = 1 / 正指数次幂。且原创 2017-07-14 17:24:34 · 405 阅读 · 0 评论 -
剑指Offer_面试题10_二进制中1的个数
题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。这一题与 牛客网_华为机试_015_求int型正整数在内存中存储时1的个数 (十进制转二进制)基本一致,解法请参考。主要注意的点在于千万不要用模2取余法来统计2的个数,不然面试会死的很惨。首先除法的效率比移位运算要低得多,在实际编程中应尽可能地用移位运算符代替乘除法。下面主要写一下剑指Offer的拓展题相关题目:原创 2017-07-14 13:32:55 · 315 阅读 · 0 评论 -
剑指Offer_面试题09_斐波那契数列
题目一:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。解析:一直以来很多C语言教科书在讲递归函数的时候总会拿斐波那契数列作为例子。但是这不意味这Fibonacci的最合适的解法就是用递归来实现。如果面试问道这题然后用递归解,那基本就GG了。因为递归调用过程中有很多重复计算,而且重复的数量随着n的增加而剧增,实际上斐波那契递归时间复杂度是以n的指数级的方式递增,计算F(100原创 2017-07-14 10:15:56 · 561 阅读 · 0 评论 -
剑指Offer_面试题07_用两个栈实现队列
题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。//队列声明如下template class CQueue{public: CQueue(void) {} ~CQueue(void) {} void push(const T& node); T pop(); void printEmu();private: stack sta原创 2017-07-12 17:22:15 · 319 阅读 · 0 评论 -
剑指Offer_面试题08_旋转数组的最小数字
思路: 如序列 3,4,5,1,2 观察到数组旋转后可以分为两个部分,两个排序的子数组,而且前面的元素都不小于后面数组的元素。而且最小值元素刚好是这两个数组的分界线。在有序数组中可以使用二分查找法实现O(logn)的查找。本题的数组一定程度上也是有序的,因此可以使用二分法的思想来寻找这个最小元素。如上图所示,a中:array[mid] >= array[p2]说明mid所指还在原创 2017-07-13 15:31:28 · 285 阅读 · 0 评论 -
剑指Offer_面试题05_从尾到头打印链表
输入一个链表,从尾到头打印链表每个节点的值。链表结点定义如下:struct ListNode{ int val; ListNode* next;};是否能够修改链表的结构取决于面试官的需求,因此在面试的时候需要我们询问清楚面试官的要求。通常打印是个只读操作,因此这里假定不能修改链表的结构。考虑到先进后出的特性,可以使用栈来实现逆向输出。在链表操作过程在,特别注意循环条件以及当循原创 2017-07-11 20:19:30 · 349 阅读 · 0 评论 -
剑指Offer_面试题06_重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。先序:{1,2,4,7,3,5,6,8}中序:{4,7,2,1,5,3,8,6}分析一波:先手动重建一次二叉树,找到重建的规律。首先我们取先序序列第一位原创 2017-07-12 14:44:38 · 1991 阅读 · 3 评论 -
剑指Offer_面试题04_替换空格
题目:请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。不好解法:遍历,找空格,插“%20”,其中插入包括先移动,后赋值。这样的解法时间复杂度o(n^2)优秀解法:遍历一遍字符串,统计空格,计算出插入后的总长度。然后从字符串的后面开始复制和替换,如此,时间复杂度o(n)原创 2017-07-10 23:55:26 · 367 阅读 · 0 评论 -
剑指Offer_面试题12_打印1到最大的n位数
题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印1、2、3一直到最大的3位数即999。陷阱:这个题目看似简单,我们先求出最大的n位数,然后for循环从1开始打印。void PrintToMax(int n){ int number = i; int i = 0; while(i++ < 10) number *= 10;原创 2017-07-17 15:06:16 · 605 阅读 · 0 评论 -
剑指Offer_面试题13_在O(1)时间删除链表结点
题目:给定单项链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该结点。分析:一般来说删除一个结点必须要知道他的前驱,这样才能让他的前驱的后继指向它的后继而“绕过”它,但这样时间复杂度就为O(n)了,必须得知道前驱。查前驱的时间复杂度为O(n), 但是查后继的复杂度为O(1), 可以把问题转换为删除后继,降低时间复杂度。首先复制后继到自身,然后删除后继就可以了。但是注意链表的几种特原创 2017-07-17 15:15:05 · 423 阅读 · 0 评论 -
剑指Offer_面试题28.5_字符串的排列扩展_排列组合_八皇后问题
剑指Offer_面试题28_字符串的排列 实现了字符排列、去重的问题,由此可以扩展出很多问题如组合问题。扩展1字符组合问题。如输入三个字符a、b、c,则他们的组合有a、b、c、ab、ac、bc、abc。分析:与排列解法一致,把问题分解。假设我们要在10个字符中取3个字符组合。那么我们把这10个字符分为两部分:第一个字符和其余9个字符。如果组合里包含第一个字符,那么就在剩余9个字符中原创 2017-08-10 16:42:07 · 453 阅读 · 0 评论 -
剑指Offer_面试题28_字符串的排列
题目描述输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。输入描述:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。分析:复杂问题分解成小问题。首先确定第一个位置的字符,即:把第一个字符和其他位置字符交换。如:{a,b,c原创 2017-08-10 11:36:35 · 468 阅读 · 0 评论 -
剑指Offer_面试题19_二叉树镜像
题目描述操作给定的二叉树,将其变换为源二叉树的镜像。输入描述:二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 7 5原创 2017-08-02 15:24:01 · 302 阅读 · 0 评论 -
剑指Offer_面试题18_树的子结构
题目描述输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)分析:这里说的子结构不是子树,只是根据值来判断,更像是“包含”关系吧。首先需要在A树中找到和B根节点值一样的结点,然后判断A的子树和B是否结构和值相同。在A中找到和B的根结点值相同的操作等同于二叉树遍历,用先序遍历逻辑上自然点把。找到这个结点,开始判断两个树是否相同。同样采用递归思想,原创 2017-08-02 15:08:45 · 258 阅读 · 0 评论 -
剑指Offer_面试题27_二叉搜索树与双向链表
题目描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。分析:题目的意思是用二叉树结点指针left、right代替pre、next构成双向链表。二叉搜索树的中序序列有序,只要把结点按照中序遍历的顺序链接起来就行。但是需要知道中序的前一个结点。为了方便获取前一个结点,首先用中序遍历非递归方法,即使用栈来遍历,实现链接。原创 2017-08-08 17:20:43 · 337 阅读 · 0 评论 -
剑指Offer_面试题14_调整数组顺序使奇数位于偶数前面
题目描述(剑指offer原版)输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分。分析:两个指针,p指向头,q指向尾,p向后遍历到偶数,q向前遍历到奇数,交换值,继续++p,--q直到p扩展性,可以把判断奇偶的功能封装成返回bool的函数,作为参数传入排序函数中。#include #include //判原创 2017-07-24 10:57:26 · 330 阅读 · 0 评论 -
剑指Offer_面试题26_复杂链表的复制
题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)分析:一般来说是分两步,首先复制原始链表上的每一个结点,并用next链起来,第二步设置每个结点的random指针。但直接这样做时间复杂度很高,达到O(n^2)级别。原创 2017-08-07 21:17:01 · 319 阅读 · 0 评论 -
剑指Offer_面试题25_二叉树中和为某一值的路径
题目描述输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。分析:不要被问题吓到,感觉很复杂。找个例子来分析一下,找规律: 10 5 12 4 7原创 2017-08-07 16:04:04 · 300 阅读 · 0 评论 -
剑指Offer_面试题42_翻转单词顺序 VS 左旋转字符串
题目一:输入一个英文句子,翻转句子中的单词的顺序,但单词内的字符顺序不变,为了简单起见,标点符号作为字母处理。如:"I am a student!" 翻转为 "student! a am I"分析:可以截取每个词然后拼接,但是很麻烦。观察单词的规律可以看出,可以先翻转每个单词,然后在对整个字符串进行翻转就可以得到结果;或者先翻转,后逐个翻转。class Solution {publi原创 2017-09-05 16:52:19 · 534 阅读 · 0 评论