剑指offer
文章平均质量分 53
小胡_uYou
这个作者很懒,什么都没留下…
展开
-
面试题47:不加加减乘除做加法
题目:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。 思路是,考虑位运算。先不考虑进位,0+0为0,1+1为0,0+1为1,1+0为1.这正好是异或。然后考虑进的位,只有1+1才有进位,而且进位到前一位,相当于左移一位,然后再将前面的与进位的重复前面的加法。代码如下:class Solution {public: int Add(int原创 2016-07-21 20:14:37 · 285 阅读 · 0 评论 -
面试题59:对称的二叉树
题目:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL),原创 2016-07-28 19:42:44 · 285 阅读 · 0 评论 -
面试题58:二叉树的下一个节点
题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。代码如下:using namespace std;struct TreeLinkNode { int val; struct TreeLinkNode *left; struct TreeLinkNode *right;原创 2016-07-28 17:27:08 · 300 阅读 · 0 评论 -
面试题57:删除链表中的重复节点
题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。 代码如下:struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x)原创 2016-07-28 16:49:35 · 293 阅读 · 0 评论 -
面试题56:链表中环的入口节点
题目:一个链表中包含环,请找出该链表的环的入口结点。 这道题借助于前面的链表的倒数第K个节点的思想,考虑快慢指针。考虑当知道了链表的环中所含的节点数目,用一个快指针先走这么多个节点,再用慢指针,两个同时走,此时他们相遇的第一个节点就是链表的入口节点。下面问题就转换为求链表环的节点数目。 考虑链表是否成环,同样用快慢指针,当他们相遇的那个节点,肯定是环内的节点,再让它自己一步步走原创 2016-07-28 16:00:30 · 269 阅读 · 0 评论 -
面试题40:数组中只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 这其实是除了有一个数字外,其它数字都出现两次的变种。只有一个数字不同的时候,可以采用异或来做。但此处是两个不同。书上给出的方法是先异或,得到结果值。然后在结果中,从右往左找到第一位是1的位号。由此考虑将数组分为两个数组。这样每个数组分别异或即可得到答案。 代码如下,其中要原创 2016-07-18 15:17:11 · 371 阅读 · 0 评论 -
面试题31:连续子数组的最大和
题目:输入一个整形数组。数组中有正数也有负数。数组中一个或者连续多个整数组成的一个子数组。求所有的子数组和的最大值。要求时间复杂度为O(n)。 这题可以用典型的动态规划来解。可以找到规律,考虑声明一个数组a[len],m[i]代表取前面i个数时它的子数组的最大值。考虑第i个数,当前面i-1个数的最大值是m[i-1];此时m[i]=max(m[i-1]+a[i],a[i]);代码原创 2016-07-06 22:51:13 · 230 阅读 · 0 评论 -
面试题30:最小的K个数
题目:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。 首先考虑用一个堆去维护最小数的序列。可是c++中自己去实现一个堆感觉代码有点多了。看了下书上推荐用set。它的底层实现就是红黑树。代码如下。class Solution {public: vector GetLeastNumbers_Solut原创 2016-07-06 21:59:40 · 221 阅读 · 0 评论 -
面试题29:数组中出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 这题要做出来比较简单,但是要考虑优化就不那么容易了。首先,写个简单的 。class Solution {public: int MoreThanHalf原创 2016-07-06 17:10:57 · 252 阅读 · 0 评论 -
面试题39:二叉树的深度
题目:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 这题可以用递归做,较为简单,代码如下: struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x),原创 2016-07-17 11:45:14 · 246 阅读 · 0 评论 -
面试题38:数字在排序数字中出现的次数
题目:统计一个数字在排序数组中出现的次数。 由于是排序数组,考虑二分查找的思想。时间复杂度O(lgn). 代码如下: class Solution {public: int GetNumberOfK(vector data ,int k) { return GetNumberOfK(data,0,data.size()-1,k);原创 2016-07-16 15:12:24 · 221 阅读 · 0 评论 -
面试题28:字符串的排列
题目:输入一个字符串,打印该字符串的字符的所有排列。 全排列问题面试中经常看到,思想是开始取第一个字符,然后求后面字符的全排列。再分别将第一个字符与后面的字符交换,再全排列。代码如下: class Solution {public: vector Permutation(string str) { vector vect;原创 2016-07-05 21:05:39 · 195 阅读 · 0 评论 -
面试题41:和为s的两个数字VS和为s的连续正数序列
题目:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。输出描述,对应每个测试案例,输出两个数,小的先输出。代码如下:class Solution {public: vector FindNumbersWithSum(vector array,int sum) { map map1;原创 2016-07-18 16:58:48 · 266 阅读 · 0 评论 -
面试题60:把二叉树打印成多行
题目:从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。 struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { }原创 2016-07-28 20:19:50 · 275 阅读 · 0 评论 -
面试题61:按之字形顺序打印二叉树
题目:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。 其实这题和之前的60题其实差不多,完全可以获得的正序的部分再逆序,但书上介绍了另一种方法,就按书上的写了。 struct TreeNode { int val; struct TreeNode *left;原创 2016-07-29 15:17:43 · 1102 阅读 · 0 评论 -
面试题46:求1+2+...+n
题目:要求不能使用乘除,,for,while,if,else switch,case等以及条件判断语句。 这题太开放了,直接看的书上的答案。 #include "stdafx.h"#include using namespace std;typedef unsigned int(*fun)(unsigned int);unsigned int s1(原创 2016-07-21 17:17:02 · 230 阅读 · 0 评论 -
面试题67:机器人的运动范围
题目:地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子? 这一题比上一题容易,用变相原创 2016-08-01 11:30:43 · 306 阅读 · 0 评论 -
面试题66:矩阵中的路径
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据原创 2016-08-01 10:29:19 · 850 阅读 · 0 评论 -
面试题45:圆圈中最后剩下的数字
题目:每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直原创 2016-07-20 21:07:45 · 348 阅读 · 0 评论 -
面试题44:扑克牌的顺子
题目描述 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11原创 2016-07-20 19:25:37 · 998 阅读 · 1 评论 -
面试题65:滑动窗口的最大值
题目:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5原创 2016-07-31 16:19:08 · 810 阅读 · 0 评论 -
面试题43:n个骰子的点数
题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s所有可能的值出现的概率。 该题是典型的动态规划问题。n个骰子它的和显然和前面n-1个骰子的状态有关。可以一步步划分来求,一般考虑设个数祖,一个记录当前是第多少个骰子,一个记录总和多少,还要记录总和的概率,因此此处考虑设个二维数组,p[m][n],m表示当前骰子数值,n代表当前点数。p[m][n]代表出现的次数或原创 2016-07-20 16:58:00 · 368 阅读 · 0 评论 -
面试题64:数据流中的中位数
题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 考虑将流中的数据分为相同数量的两部分,也就是两个堆,一个堆中的数据全都小于另外一个堆,小一点的堆里作为最大堆,大一点的堆作为最小堆,这样这两个堆顶元素就与所求的中位数相关。class Sol原创 2016-07-30 21:52:48 · 1002 阅读 · 0 评论 -
面试题42:翻转单词顺序
题目:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?class Solutio原创 2016-07-19 19:51:14 · 254 阅读 · 0 评论 -
面试题63:二叉搜索树的第K个节点
题目:给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val原创 2016-07-29 20:15:34 · 748 阅读 · 0 评论 -
面试题62:序列化二叉树
题目:请实现两个函数,分别用来序列化和反序列化二叉树。这里没有规定序列化的方式。class Solution {public: char* Serialize(TreeNode *root) { if(!root) return "$"; string r = to_string(root->val); r.push_原创 2016-07-29 17:12:56 · 293 阅读 · 0 评论 -
面试题55:字符流中第一个不重复的字符
题目:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。 输出描述::如果当前字符流没有存在出现一次的字符,返回#字符。这种题目我一般是采用一个map去记它的计数,书上是采用一个数组去计数,采用数组的好处是,在字符很多很多的情原创 2016-07-27 09:21:54 · 452 阅读 · 0 评论 -
面试题54:表示数值的字符串
题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。 表示数值的字符串遵循: [sign]intergal-digits[.[fractional-digits]][e|E[si原创 2016-07-26 22:07:45 · 637 阅读 · 0 评论 -
面试题51:数组中重复的数字
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。 这题如果考虑用一个map的话,时间复杂度O(n),空间复杂度也是O(n)。代码如下:class Soluti原创 2016-07-24 21:02:15 · 308 阅读 · 0 评论 -
面试题22:栈的压入,弹出系列
题目:输入两个整数序列。第一个序列表示栈的压入顺序,请判断第二个序列是否是栈的弹出顺序。假设压入栈的所有数字均不相等。例如1,2,3,4,5是某栈的压入序列,序列4,5,3,2,1是该栈序列对应的一个弹出序列,但是4,3,5,1,2就不可能是该压栈的弹出序列。 看到该题目开始想的是用一个栈去实现。思路也是对的,但是思路出来了代码没写出来,各种错误,心里很急躁啊,静不下心来调,只有看书原创 2016-07-01 17:52:31 · 272 阅读 · 0 评论 -
面试题21:包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数,调用min,push及pop的时间复杂度为O(1)。 这个题目push和pop都好做,但是min感觉不好做。思考可以用一个临时量记录min的值。但是没想到用一个数据结构去保存每次入栈、出栈的最小值。哎。。。 看了下原文,是用另外一个栈去维护最小值,好吧。。。代码如下: cl原创 2016-06-30 20:43:28 · 239 阅读 · 0 评论 -
面试题20:顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每个数字。 这个问题之前在leecode上也碰到过,当时有人写了一种挺好的方法,借助于游戏设置上下左右的方法,具体有点不记得了。这道题看上去简单,但是写起来不容易,各种情况,开始很难考虑全,先写书上提到的方法吧。 class Solution {public: vector printMatrix(vector >原创 2016-06-30 20:02:32 · 324 阅读 · 0 评论 -
面试题49:将字符串转换成整数
题目:实现类似atoi函数。 本题主要考虑各种测试条件。 代码如下:class Solution {public: int StrToInt(string str) { if(str=="") return 0; int i=0; bool neg=false;原创 2016-07-22 20:18:36 · 289 阅读 · 0 评论 -
面试题18:树的子结构
题目:输入两颗二叉树A和B ,判断B是不是A的子结构。 想到关于二叉树的题目,基本可以按照递归的思路来做,很快写出以下代码:struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL)原创 2016-06-06 09:54:02 · 351 阅读 · 1 评论 -
面试题17:合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表使新链表仍然是递增排序的。 题目还算简单,就是要考虑的特殊情况挺多的。代码如下: struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};class Solution {pub原创 2016-06-05 22:39:42 · 208 阅读 · 0 评论 -
面试题16:反转链表
题目:反转链表。输入链表的头结点,反转输出反转后链表的头结点。 这种链表操作的题之前做过,还专门写过链表反转的东东。咋一看,觉得这用递归不so easy吗。结果,papa打脸了,写了半个多小时才出来,面试肯定就挂了。都要哭了,代码写一万遍都不会啊。 先用递归实现: struct ListNode { int val; str原创 2016-06-05 11:13:25 · 207 阅读 · 0 评论 -
面试题15:链表中倒数第k个节点
题目:输入一个链表,输出该链表中倒数第k个节点。从1开始计数,如链表有1,2,3,4,5,6.倒数第三个节点是值为4的节点。 可以采用两个指针,思路比较清晰,但是就是一些边界条件很难考虑全,比如k超出了链表的长度。 struct ListNode { int val; struct ListNode *next; ListNode(int x) :val(x), next(原创 2016-06-04 17:09:20 · 246 阅读 · 0 评论 -
面试题19:二叉树的镜像
题目:完成一个函数,输入一个二叉树,输出它的镜像。 该题考虑递归较为简单。先交换两个子节点,然后再递归求解。画一个图可以较好的理解。博客上画比较困难,在此就不多画了。原创 2016-07-02 10:09:01 · 188 阅读 · 0 评论 -
面试题23:从上往下打印二叉树
题目:从上往下打印二叉树的每个节点,同一层的节点按照从左到右的顺序打印。 这题挺简单的。相当于广度优先搜索,考虑用队列来做。如果是深度优先,可以使用堆栈或者采用递归。代码如下:struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val原创 2016-07-02 10:18:37 · 262 阅读 · 0 评论 -
面试题24:二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。是返回true,否则返回false.假设输入的数组元素均不相同。 二叉搜索树左边节点小于根节点值,右边节点值大于根节点值。首先找到根节点,然后判断将前面的归于左子树,右边归于右子树。如果右边中出现了比根节点值小的情况。则不是树的后序遍历节点,可以用递归来做。 代码如下: class原创 2016-07-02 11:51:45 · 250 阅读 · 0 评论