![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
剑指Offer
文章平均质量分 63
思翊
Hello , world.
展开
-
剑指Offer之 - 树中两个结点的最低公共祖先
题目:求树中两个节点的最低公共祖先。思路一:——如果是二叉树,而且是二叉搜索树,那么是可以找到公共节点的。二叉搜索树都是排序过的,位于左子树的节点都比父节点小,而位于右子树上面的节点都比父节点大。如果当前节点的值比两个结点 的值都大,那么最低的共同的父节点一定是在当前节点的左子树中,于是下一步遍历当前节点的左子节点。如果当前节点的值比两个结点的值都小,那么最低的原创 2015-04-29 16:07:14 · 849 阅读 · 0 评论 -
剑指Offer之 - 丑数
题目: 我们把只包含因子2、3和5的数称作丑数(UglyNumber)。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第1500个丑数。思路:1、 写一个函数判断一个数是不是丑数,然后每判断一个数是丑数,则计数+1 ,直到计数到达1500。代码:#include #include using namespace原创 2015-04-23 15:25:34 · 907 阅读 · 0 评论 -
剑指Offer之 - 和为s的两个数字 VS 和为s的连续正数序列
题目:1、输入一个递增排序的数列和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可。类似3Sum和4Sum。分别参考:http://blog.csdn.net/u012243115/article/details/41361781 和 http://blog.csdn.net/u012243115/article/details/41719831原创 2015-04-26 14:31:23 · 390 阅读 · 0 评论 -
剑指Offer之 - 不用加减乘除做加法
题目:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/、四则运算符号思路:两数异或得到没有进位的数,两数相与得到进位结果,进位左移一位,再与异或结果相异或,直至进位为0代码:#include using namespace std;//题目:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/、四则运算符号//思路:两数异或得到没有进位的数,原创 2015-04-28 10:55:08 · 402 阅读 · 0 评论 -
剑指Offer之 - 树的镜像
题目:输入一个二叉树,求该函数的镜像二叉树。镜像二叉树如下图所示:思路:左右孩子互换,然后递归调用。代码:#include using namespace std;struct BinaryTreeNode{ int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; BinaryTr原创 2015-05-05 16:47:33 · 385 阅读 · 0 评论 -
剑指Offer之 - 重建二叉树
题目:根据二叉树的前序和中序遍历结果,重建出二叉树(不含重复数字)思路:参考:http://blog.csdn.net/u012243115/article/details/42143549 和 http://blog.csdn.net/u012243115/article/details/42141713 。代码:#include#include#includeus原创 2015-05-02 16:23:34 · 401 阅读 · 0 评论 -
剑指Offer之 - 二叉树的深度
题目:1、求二叉树的最大深度和最小深度。2、判断一棵二叉树是不是平衡二叉树。代码:#include using namespace std;struct BinaryTreeNode{ int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; BinaryTreeNode(){} Binary原创 2015-04-26 10:51:00 · 385 阅读 · 0 评论 -
剑指Offer之 - 数组中只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。找出这两个数字。时间复杂度O(n),空间复杂度:O(1)。例如数组:int num[] = {1,1,2,3,2,5,4,5,6,6};找出3和4。代码:#include using namespace std;//功能:数组中只出现一次的数字//一个整型数组里除了两个数字之外,其他的数字都出现了两次。找出这两个原创 2015-04-26 11:28:52 · 526 阅读 · 0 评论 -
剑指Offer之 - n个骰子的点数
题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率思路1:由题目可知,最小点数之和为n,最大点数之和为6n。要想求出n个骰子的点数和,可以先把n个骰子分为两堆:第一堆只有一个,另一个有n-1个。单独的那一个可能出现从1到6的点数。我们需要计算从1到6的每一种点数和剩下的n-1个骰子来计算点数和。接下来把剩下的n-1个骰子还是分原创 2015-04-27 09:40:40 · 498 阅读 · 0 评论 -
剑指Offer之 - 栈的压入、弹出序列
题目:输入两个整数序列,第一个表示压入顺序,判断第二个序列是否是该栈的弹出序列。比如:压入序列1,2,3,4,5,则序列4,5,3,2,1是弹出序列,但是序列4,3,5,1,2就不可能是弹出序列。思路:把第一个序列的数入栈,直到遇到可第二个序列的数相等。如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。否则入栈,比如1 != 4 ,则把1入栈。直到4 == 弹出的数字4原创 2015-05-07 14:26:17 · 441 阅读 · 0 评论 -
剑指Offer之 - 从上往下打印二叉树
题目:按层打印二叉树。思路:用队列实现。代码:#include#include #includeusing namespace std;struct BinaryTreeNode{ int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; BinaryTreeNode(){}; Bin原创 2015-05-07 14:47:30 · 376 阅读 · 0 评论 -
剑指Offer之 - 包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push,pop函数的世界复杂度都是O(1)。思路:维护一个辅助栈s2,用来存储当前栈中的最小元素比如栈s1 : ,辅助栈s2就是: 代码:#include#include using namespace std;//功能:定义栈的数据结构,请在该类型中实原创 2015-05-07 14:14:49 · 400 阅读 · 0 评论 -
剑指Offer之 - 圆圈中最后剩下的数字
题目:0,1,...,n-1这n个数排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删词第3个数字,则删除的前四个数字一次是2、0、4、1,因此最后剩下的数字是3.思路:方法1:用环形链表模拟圆圈,链表可以用c++的STL库中的list来表示,删除链表其中一个结点原创 2015-04-27 15:58:22 · 443 阅读 · 0 评论 -
剑指Offer之 - 翻转单词顺序 VS 左旋转字符串
题目:1、输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student.",则输出"student. a am I"。2、字符串的左旋操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2原创 2015-04-26 15:30:21 · 519 阅读 · 0 评论 -
剑指Offer之 - 数组中的逆序对
题目:在数组中的两个数字如果前面一个数字大于后面一个数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。如数组{7,5,6,4}中,有5个逆序对,分别是(7,6)、(7、5)、(7,4)、(6、4)、(5、4)思路:利用归并排序的过程求解逆序对。归并排序是将数列a[l,h]分成两半a[l,mid]和a[mid+1,h]分别进行归并排序,然后再将这两原创 2015-04-24 15:34:21 · 352 阅读 · 0 评论 -
剑指Offer之 - 二叉搜索树的后续遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后续遍历的结果。思路:根据二叉搜索树的后续遍历结果的特点来判断:序列的最后一个数是根结点,且前面一部分的数 最后一个数。类似这样的数组:5,7,6,9,11,10,8如果满足上面的条件,然后再对两部分进行递归判断,否则直接返回false。代码:#include#include #includeusing原创 2015-05-07 15:08:40 · 404 阅读 · 0 评论 -
剑指Offer之 - 顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以逆时针的顺序依次打印出每一个数字。思路:按圈打印,每次打印一圈。每一圈只要知道左上角的起始点,就能算出这一圈的其他三个角。代码:#includeusing namespace std;//旋转打印二维数组void PrintMatrixInCircle(int **numbers , int columns , int rows ,原创 2015-05-07 14:07:19 · 485 阅读 · 0 评论 -
剑指Offer之 - 字符串的排列
题目:输入一个字符串,打印出该字符串中字符的所有排列。思路:DFS。代码:#include#include #include using namespace std;//功能:求字符串全排列void dfs(string str ,vector &result , int len , int start){ if(start == len) result原创 2015-05-07 16:20:40 · 449 阅读 · 0 评论 -
剑指Offer之 - 二叉树中和为某一值的路径
题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。思路:深度优先搜索。代码:#include#include using namespace std;struct BinaryTreeNode{ int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; Bina原创 2015-05-07 15:42:12 · 365 阅读 · 0 评论 -
剑指Offer之 - 复杂链表的复制
题目:复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。实现一个函数可以复制这个复杂链表。思路:先正常复制一个结点,并把这个复制的结点置于当前结点后面。其后,再复制链表结点的m_pSibling指针,由前一个结点求出它的m_pSibling,则新结点的m_pSibling就是它的m_pSibling结原创 2015-05-07 16:08:22 · 528 阅读 · 0 评论 -
剑指Offer之 - 扑克牌的顺子
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10的数字为本身,A为1,J为12,K为13,而大、小王可以看成任意数字。(用0表示,可以代替任意数)思路:先排序,然后求0(大王或者小王)的个数,最后再求相邻两个数的差的总和。如果0的个数> 总和,则是顺子,如果 如果出现对子,则一定不是顺子代码:#include//#includ原创 2015-04-27 14:32:22 · 409 阅读 · 0 评论 -
剑指Offer之 - 从尾到头打印链表
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。思路:1、栈2、递归代码:#include#include #includeusing namespace std;struct ListNode{ int m_nKey; ListNode *m_pNext; ListNode(){} ListNode(int value):m_nKey(v原创 2015-05-02 16:20:30 · 669 阅读 · 0 评论 -
剑指Offer之 - 第一个只出现一次的字符
题目:在字符串中找出第一个只出现一次的字符。思路:使用数组模拟哈希表。代码:#include using namespace std;//功能:查找字符串中第一个次数不为1的字符//先用哈希数组统计一下字符串中每个字符出现的次数,然后再遍历一下,如果次数为1,就直接返回char FirstNotRepeatingChar(char *pString){ if(原创 2015-05-12 10:51:03 · 397 阅读 · 0 评论 -
剑指Offer之 - 数组中出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过数组长度的一半,原创 2015-05-12 09:16:06 · 358 阅读 · 0 评论 -
剑指Offer之 - 数值的整数次方
题目:实现函数double Power(double base , int exponent) ,求base 的 exponent次方。不考虑大数问题。思路:1、n次迭代2、二分递归法考虑情况:1、底数为0(如何判断double类型为0),指数为负(无效输入) 2、指数为负时,先算正,再求倒数代码:#include us原创 2015-05-04 15:52:43 · 355 阅读 · 0 评论 -
剑指Offer之 - 连续子数组的最大和
题目:输入一个整数数组,数组里有正数也有负数。求所有子数组的和的最大值。思路:方法很多,这里讲两种1、举例分析数组的规律。2、动态规划。代码:#include #include using namespace std;//功能:连续子数组的最大和int FindGreatestSumOfSubArray(vector num){ int len = n原创 2015-05-12 10:05:56 · 378 阅读 · 0 评论 -
剑指Offer之 - 数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数。如{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4.思路:如果先找到数字,然后再往前后遍历,复杂度有可能退化到O(n) ,比如数组全是3。二分查找,直接找第一次出现的次数和最后出现的次数。代码:#include using namespace std;//功能:统计一个数字在排序数组中出原创 2015-04-24 17:07:02 · 349 阅读 · 0 评论 -
剑指Offer之 - 二进制中1的个数
题目:求一个数的二进制表示形式中的1的个数。思路:1、用1,从n的后面往前依次与n相与即可2、把一个数-1的结果就是把它的二进制形式的最后一个1去掉,而后面的全变成1,如1111 1100 - 1 = 1111 1011然后二者相与,得到的结果相比于原来的数就减少1个1,直到结果为0。即 1111 1100 & 1111 1011 = 1111 1000 。代码:#in原创 2015-05-02 17:15:26 · 366 阅读 · 0 评论 -
剑指Offer之 - 旋转数组的最小数字
题目:找出旋转数组中的最小数字。思路:有两种情况,数组没有重复数字和有重复数字分别参考:http://blog.csdn.net/u012243115/article/details/41923667 和 http://blog.csdn.net/u012243115/article/details/41924217 。代码:#include using namespac原创 2015-05-02 16:32:55 · 338 阅读 · 0 评论 -
剑指Offer之 - 用两个栈实现队列
题目:用两个栈实现一个队列。思路:[1] 入队列就直接把数据放到第一个栈里[2] 出队列就判断第二个栈是否为空,不为空的话,第二个栈直接出栈结果就是出队列,若为空就把第一个栈里的数据转移到第二个栈里,然后第二个栈再出栈代码:#include #include using namespace std;//功能:用两个栈实现一个队列的添加元素和删原创 2015-05-02 16:28:10 · 484 阅读 · 0 评论 -
剑指Offer之 - 两个链表的第一个公共结点
题目:输入两个链表,找出他们的第一个公告结点。思路:长链表先走,然后一起走。代码:#include using namespace std;//功能:输入两个链表,找出他们的第一个公共结点。struct ListNode{ int m_nKey; ListNode *m_pNext; ListNode(){} ListNode(int x):m_nKey(x原创 2015-05-12 11:00:10 · 436 阅读 · 0 评论 -
剑指Offer之 - 合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。思路:1、迭代(注意定义虚拟头结点)。2、递归。代码:#include using namespace std;struct ListNode{ int m_nValue; ListNode *m_pNext; ListNode(){} ListNode(int x):m_n原创 2015-05-05 16:30:12 · 396 阅读 · 0 评论 -
剑指Offer之 - 在O(1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。思路:3种情况:1、只有一个结点,且要删除的就是第一个结点???遇到链表时一定要单独考虑只有一个结点的情况 2、要删除的结点不是最后一个结点,这时不需要查找,直接用后面一个结点的值代替前面一个结点,然后删除后一个结点 3、要删除的结点是最后一个结点,这时需要先遍历到倒数第二个结点代码原创 2015-05-05 14:39:15 · 404 阅读 · 0 评论 -
剑指Offer之 - 二维数组中的查找
题目:在一个二维数组中查找一个数,二维数组的特点是每一行和每一列都是从小到大排列。思路:从右上角开始判断,如果target大于它,向下,如果target小于它,向左。代码:#include #include using namespace std;//在一个二维数组中查找一个数,二维数组的特点是每一行和每一列都是从小到大排列//思路:从第一行最后一个数开始和numbe原创 2015-05-02 16:11:31 · 320 阅读 · 0 评论 -
剑指Offer之 - 替换空格
题目:把字符串中的空格用%20代替。思路:统计空格个数,从后往前赋字符。代码:#include using namespace std;//函数功能:把字符串中的空格用%20代替//思路:统计空格个数,从后往前赋字符//注意点:要判断字符串的字节个数是否够替换后的字符数,如果不够则不能替换void ReplaceBland(char string[]原创 2015-05-02 16:13:07 · 381 阅读 · 0 评论 -
剑指Offer之 - 反转链表
题目:输入一个链表头结点,反转该链表,并输出反转后链表的头结点。思路:……代码:#include using namespace std;struct ListNode { int m_nKey; ListNode *m_pNext; ListNode(){} ListNode(int x):m_nKey(x),m_pNext(NULL){}};//功能:原创 2015-05-05 16:17:38 · 366 阅读 · 0 评论 -
剑指Offer之 - 链表中倒数第k个结点
题目:输入一个链表,输出该链表中倒数第k个结点。思路;两个指针。一个指针先走k步,然后两个指针同时走,直到第一个指针走到最后,这样第二个指针就到了倒数第k个结点。注意:k有可能大于链表长度。代码:#include using namespace std;struct ListNode{ int m_nValue; ListNode *m_pNext; List原创 2015-05-05 16:08:06 · 304 阅读 · 0 评论 -
剑指Offer之 - 调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数维护数组的后半部分。思路:两个指针,一个指向开头,一个指向末尾。代码:#includeusing namespace std;//功能:把数组里的奇数放在前面,偶数放在后面//解法1:两个指针,一个在前一个在后void ReorderOddEven(int *pDa原创 2015-05-05 15:43:04 · 360 阅读 · 0 评论 -
剑指Offer之 - 打印1到最大的n位数
题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数,即999.思路:如果输入n很大,则不能用int或者long long来表示,这里用字符串来模拟数字,只需要n+1位即可。代码:#include using namespace std;//功能:给定数组x,求从1到x位最大数,并打印出来。即如果x = 2,则打印1 2原创 2015-05-05 14:25:12 · 385 阅读 · 0 评论 -
剑指Offer之 - 树的子结构
题目:输入两棵二叉树A和B,判断B是不是A的子结构。思路:先在A中找到一个结点的值和B的根结点值相同的结点,然后再判断以这个结点为根结点的数和树B是否相等(不是相等,而是B是否是A的子树)。代码:#include using namespace std;struct BinaryTreeNode{ int m_nValue; BinaryTreeNode *m_原创 2015-05-05 16:41:17 · 356 阅读 · 0 评论