剑指Offer
三名狂客
success without applause,diligence without reward!Becoming、Cognifying、Flowing、Screening、Accessing、Sharing、Filtering、Remixing、Interacting、Tracking、Questioning、Beginning.
展开
-
程序员面试金典
偶然发现牛客网程序员面试金典在线编程题和学习算法经验:原创 2017-11-08 18:11:42 · 816 阅读 · 0 评论 -
按照之字形顺序打印二叉树
问题:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。例如:分析:按照广度优先遍历来遍历二叉树,但是需要按照之字形来打印:奇数行从左到右,跟BFS的遍历顺序一样,而偶数行从右到左,跟BFS的遍历顺序相反。因此可以通过两个栈来实现,一个实现先进先出,即入栈顺序为右子节点、左翻译 2016-12-23 13:22:09 · 430 阅读 · 0 评论 -
把二叉树打印成多行
问题:从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印到一行。例如:打印结果: 8 6 105 7 9 11分析:为了把二叉树的每一行单独打印到一行里,我们需要两个变量:一个变量表示在当前层中还没有打印的结点数,另一个变量表示下一层结点的数目。//按照行打印二叉树void Print(BinaryTreeNode翻译 2016-12-23 13:15:55 · 530 阅读 · 0 评论 -
对称的二叉树
问题:请实现一个函数来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。详细的设计代码如下:bool isSymmetrical(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);//判断是否为对称树bool isSymmetrical(BinaryTreeNode* pRoot){ return翻译 2016-12-23 13:07:37 · 345 阅读 · 0 评论 -
二叉树的下一个结点
问题:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。思路:此题包含三步:1. 如果此节点有右子树,下一个节点为右子节点的最左边的节点。2.如果此节点没有右子树,并且如果此节点是其父节点的左子节点,则下一个节点为父节点。3.如果此节点没有右子树,并且如果此节点是其父节点的右子节点,则一直向上找翻译 2016-12-23 13:01:25 · 375 阅读 · 0 评论 -
八款实用软件
1、oCam:这款免费屏幕录制捕捉工具,编码功能强大,支持游戏录像,可录制任何区域,可选全屏模式或自定义区域截图;还可捕捉到正在播放的声音;非常简单易用,而且完全免费。操作也非常简单:1、设置屏幕录制范围;2、点击录制按钮;3、停止录制并保存;即可完成录像!oCam2、Ashampoo Snap:阿香婆截图软件,德国老牌截图软件,专业的屏幕截图软件,支持抓取屏幕上的一切内容转载 2016-12-23 09:35:19 · 794 阅读 · 0 评论 -
删除链表中重复的结点
问题:在一个排序的链表中,如何删除重复的结点?例如下图情况:详细的实现代码如下://删除重复的结点void deleteDuplication(ListNode** pHead){ if(pHead == NULL || *pHead == NULL) return; ListNode* pPreNode = NULL;翻译 2016-12-22 18:36:58 · 391 阅读 · 0 评论 -
链表中环的入口结点
问题:一个链表中包含环,如何找出环的入口结点?例如下图环的入口结点为3.详细的设计代码如下:ListNode* MeetingNode(ListNode* pHead){ if(pHead == NULL) return NULL; ListNode* pSlow = pHead->m_pNext; if(pSlow == NULL)翻译 2016-12-22 18:32:31 · 324 阅读 · 0 评论 -
字符流中第一个不重复的字符
问题:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。 方法1:将字符流保存起来通过哈希表统计字符流中每个字符出现的次数,顺便将字符流保存在string中,然后再遍历string,从哈希表中找到第一个出现一次的字符;方法翻译 2016-12-22 18:06:53 · 409 阅读 · 0 评论 -
表示数值的字符串
问题:请实现 一个函数用来找出字符流中第一个只出现一次的字符。/** Question Description:* (Question 12 in ) How do you check whether a string stands for a number or not?* Numbers include positive and negative integers and float翻译 2016-12-22 18:00:39 · 402 阅读 · 0 评论 -
正则表达式匹配
问题:请实现一个函数用来匹配包括’.’和’*‘的正则表达式。模式中的字符’.’表示任意一个字符,而’*‘表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与串"a.a”和"ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配.#include bool matchCore(char* string, char*翻译 2016-12-22 16:30:17 · 420 阅读 · 0 评论 -
构建乘积数组
问题:给定一个数组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]看成C[i],D[i]两个部分的乘积所的,C[i]=A[0]*A[1]*.....*A[i-1],D[i]=A[0]*A[1]*.....*A[i-1]#include #i翻译 2016-12-22 16:16:52 · 636 阅读 · 0 评论 -
数组中重复的数字
问题:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 详细的设计代码如下:#include // Parameters:// numbers:翻译 2016-12-22 16:04:03 · 453 阅读 · 0 评论 -
案例二 树中两个结点的最低公共祖先
问题: 树中两个结点的最低公共祖先. (1)是一颗二叉树,并且是二叉搜素树(根据二叉搜素树的性质求解) (2)普通树中结点有指向父结点的指针(演变为两个链表求解第一个公共结点) (3)一棵普通的树,树中的结点没有指向父结点的指针(最复杂的情况)通用的解法如下://记录结点的路径bool GetNodePath(TreeNode* pRoot,翻译 2016-12-21 20:44:45 · 406 阅读 · 0 评论 -
案例一 把字符串转换成整数
把字符串转换成整数:(考虑输入空指针,边界值测试,功能测试)//将字符串转换成整数long long StrToIntCore(const char* str, bool minus);//判断输入的字符串是否非法enum Status {kValid = 0, kInvalid};int g_nStatus = kValid;int StrToInt(const char* st翻译 2016-12-21 20:28:48 · 510 阅读 · 0 评论 -
丑数
问题:把只包含因子2、3、5的数称作丑数,求从小到大的顺序的第1500个丑数。// ====================算法1的代码:穷举====================bool IsUgly(int number){ while(number % 2 == 0) number /= 2; while(number % 3 == 0)翻译 2016-12-15 18:36:55 · 378 阅读 · 0 评论 -
把数组排成最小的数
问题:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,求所有数字中的最小一个. 详细代码如下:int compare(const void* strNumber1, const void* strNumber2);// int型整数用十进制表示最多只有10位const int g_MaxNumberLength = 10; char* g_StrCombine1 = n翻译 2016-12-15 18:32:41 · 504 阅读 · 0 评论 -
序列化二叉树
问题:请实现两个函数,分别用来序列化和反序列化二叉树。这里序列化指的是将一棵二叉树保存到文件中,反序列化就是从文件中读取二叉树结点值重构原来的二叉树。详细的实现代码如下://序列化void Serialize(BinaryTreeNode* pRoot, ostream& stream){ if(pRoot == NULL) { stream << "$翻译 2016-12-23 13:27:30 · 377 阅读 · 0 评论 -
二叉搜索树的第k个节点
问题:给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。 分析:因为是二叉搜索树,所以可以用中序遍历的方式存储然后输出第k个结点,要注意为0和大于结点大小的K值;详细的设计代码如下://二叉搜索树的第k个节点BinaryTreeNode* KthNode(Binar翻译 2016-12-23 13:35:08 · 531 阅读 · 0 评论 -
面试中的各项能力
面试中的各项能力一、沟通能力和学习能力 面试官对沟通能力、学习能力的考查贯穿整个面试的始终,他们会关注面试者的言谈举止,通常面试官认为善于提问的人有较好的的沟通和学习能力。 二、知识迁移能力 这种能力能够帮助我们解决很多问题,有些面试官喜欢用简单的问题牵引出复杂的问题的解法,这要求面试者平时要有一定的积累,并且每做完一道题之后都要总结解题的方法。翻译 2016-12-18 15:46:52 · 649 阅读 · 0 评论 -
圆圈中最后剩下的数字(约瑟夫环问题)
问题:0,1,2,.......,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求出这个圆圈里面剩下的最后的一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前四个数字一次是2、0、4、1,因此最后剩下的数字是3.详细的设计代码如下:// ====================方法1:经典的解法,用环形链表模拟圆翻译 2016-12-20 10:54:38 · 1105 阅读 · 0 评论 -
扑克牌的顺子
问题:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字的本身,A为1,J,Q,K为11,12,13,而大小王可以看成任意数字。 详细的实现代码如下://比较两个值的大小int compare(const void *arg1, const void *arg2);//判断是否连续bool IsContinuous(int* numbers,翻译 2016-12-20 10:34:41 · 388 阅读 · 0 评论 -
n个骰子的点数
计算机作为一种工具,它的作用是用来解决实际的生产生活中的问题。程序员的工作就是把各种现实问题抽象成数学模型并用计算机的编程语言表达出来。建立模型:第一步:选择合理的数据结构表达问题;第二步:分析模型中的内在规律,并且用编程语言表达这种规律。问题:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。 详细的实现代码如下:int g_maxV翻译 2016-12-20 10:28:29 · 301 阅读 · 0 评论 -
左旋转字符串
问题:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab". 算法思想:三次旋转,第一次旋转字符前面n个字符,第二次旋转字符串的后面部分,第三次旋转整个字符串。//左旋转操作char* LeftRotateString(char* pStr,翻译 2016-12-19 19:15:44 · 331 阅读 · 0 评论 -
打印结果为S的连续序列
问题:输入一个正数S,打印出所有和为S的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以打印的结果为三个连续的序列1-5,4-6和7-8. 算法的过程如下:详细的代码如下://打印出连续的序列void PrintContinuousSequence(int small, int big);void FindContinuou翻译 2016-12-19 19:08:48 · 343 阅读 · 0 评论 -
翻转单词的顺序
问题:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和和普通字母一样处理。例如输入字符串"I am a student",则输出".student a am I" 算法思想:翻转两次就够了,第一次翻转整个句子得到"tneduts a ma I" ;第二次翻转每个单词得到".student a am I" 详细的实现代码如下:翻译 2016-12-19 19:02:51 · 525 阅读 · 0 评论 -
和为S的两个数字
问题:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得它们的和正好是S。如果有多对数字的和等于S,输出任意一对即可。 例如输入数组{1、2、4、7、11、15}和数字15.由于4+11=15,因此输出4和11. 算法的过程如下: 详细的代码如下:bool FindNumbersWithSum(int data[], int length, int su翻译 2016-12-19 18:55:38 · 310 阅读 · 0 评论 -
数组中只出现一次的数字
问题:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度为O(1). 算法思想:采取异或操作和根据结果二进制中1的位置进行划分为两个部分,然后在采取异或运算得出不同的结果。unsigned int FindFirstBitIs1(int num);bool IsBit1翻译 2016-12-19 18:44:13 · 305 阅读 · 0 评论 -
判断一棵二叉树是否为平衡二叉树
问题:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。例如下面就是一棵平衡二叉树。运用递归自底向上(从叶子结点到根结点)的思想实现的代码:// ====================方法1(自根到叶子)====================int TreeDepth(BinaryTreeNode*翻译 2016-12-19 16:55:24 · 480 阅读 · 0 评论 -
二叉树的深度
问题:输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 二叉树的定义如下: struct BinaryTreeNode { int m_nValue; BinaryTreeNode * m_pLeft ; BinaryTreeNode *翻译 2016-12-19 16:47:04 · 320 阅读 · 0 评论 -
数字在排序数组中出现的次数
问题:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4。 详细的设计代码如下:(二分查找思想)int GetNumberOfK(int* data, int length, int k){ int number = 0; if(data != NULL && length >翻译 2016-12-19 16:38:41 · 362 阅读 · 0 评论 -
剑指offer在线编程
今天偶然在牛客网上看到在线编程的试题,特此推荐网址:https://www.nowcoder.com/ta/coding-interviews?query=&asc=true&order=&page=1原创 2016-12-24 15:57:52 · 812 阅读 · 0 评论 -
回溯法 机器人的运动范围
问题:地上有个 m 行 n 列的方格。一个机器人从坐标(0,0)的格子开始移动,它每一次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于 k 的格子。例如,当 k 为 18 时,机器人能够进入方格(35,37),因为 3+5+3+7=18 但它不能进入方格(35,38),因为 3+5+3+8=19 请问该机器人能够达到多少格子?分析:和前面的矩阵翻译 2016-12-24 15:41:02 · 677 阅读 · 0 评论 -
回溯法 矩阵中的路径
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中间向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如:例如在下面的3*4的矩阵中包含一条字符串”bcced”的路径。但矩阵中不包含字符串“abcb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二格子之后,路径不能再翻译 2016-12-24 15:29:28 · 1199 阅读 · 0 评论 -
滑动窗口的最大值
问题:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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翻译 2016-12-24 15:21:22 · 468 阅读 · 0 评论 -
数据流中的中位数
问题:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有值排序之后位于中间的数值。如果数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 分析:下面总结使用了没有排序的数组、排序的数组、排序的链表、二叉搜索树、AVL数、最大堆和最小堆几种不同的数据结构的时间复杂度。思路:综合考虑用堆实现,考虑将数据序列从中间开始分为两个部分,左边翻译 2016-12-24 15:12:04 · 457 阅读 · 0 评论 -
从1到n正数中1出现的次数
问题:输入一个整数n,求从1到n这n个整数的十进制中1出现的次数。 详细实现代码如下:// ====================方法一:穷举====================int NumberOf1(unsigned int n);int NumberOf1Between1AndN_Solution1(unsigned int n){ int number =翻译 2016-12-15 18:28:49 · 466 阅读 · 0 评论 -
连续子数组的最大和
问题:输入一个整型数组,数组里有正数和负数。数组中一个或者连续的的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n).详细的实现代码如下:bool g_InvalidInput = false;//解法一:举例分析数组的规律int FindGreatestSumOfSubArray(int *pData, int nLength){ if((翻译 2016-12-15 18:24:39 · 431 阅读 · 0 评论 -
找出链表中倒数第K个结点
问题:输入一个链表,输出该链表中倒数第k个结点。本题从1开始计数,即链表的尾结点是倒数的第一个结点。例如一个链表有6个结点,从头结点开始他们的值一次是1,2,3,4,5,6。这个链表的倒数第3个结点是值为4的结点。(提高代码的鲁棒性:进行防御性编程)防御性编程是一种编程习惯,是指预见在什么地方可能会出现问题,并且为这些可能出现的问题制定处理方式。比如视图打开文件时发现文件不存在,我们可以提示用户检翻译 2016-12-06 12:39:27 · 389 阅读 · 0 评论 -
调整数组顺序使奇数位于偶数的前面
问题:输入一个整数数组,实现一个函数来调整该数组中数字的顺序使得奇数位于前半部分,偶数位于后半部分. 算法思想:维护两个指针,第一个指针初始化时指向数组的第一个数字,它只向后移动;第二个指针初始化时指向数组中的最后一个数字,它只向前移动。如果第一个指针指向数字是偶数,并且第二个指针指向的数字是奇数就交换这两个数字.对应的程序实现如下:#include "stdafx.h翻译 2016-12-06 11:10:00 · 350 阅读 · 0 评论