C++基础应用
JarrettLife
你不是成为你想要的, 你要成为你所相信的!
展开
-
树中两个结点的最低公共祖先50
题目描述:输入两个树节点,找出它们的最低公共祖先。这是一棵普通树而且没有指向父节点的指针。解题思路:使用了两个链表分别保存从根节点到输入的两个结点的路径,然后把问题转换成两个链表的最后公共节点。首先得到一条从根节点到树中某一结点的路径,借助前序遍历,VLR。找出两个输入节点的两条路径。找到这两条路径的公共结点,便是输入两个树节点的最低公共祖先。函数实现://第一步:得到输入节点路径boo原创 2016-06-22 22:07:35 · 554 阅读 · 0 评论 -
第一个只出现一次的字符36
题目描述:在字符串中找出第一个只出现一次的字符。如输入”abaccdeff”; 则输出b。解题思路:使用哈希表将字符保存为键,而值是该字符出现的次数。需扫描字符串两次,第一次扫描字符串时,每扫描到一个字符就在哈希表的对应项中把次数加1.第二次扫描时,每扫描到一个字符就能从哈希表中得到该字符出现的次数。测试用例:int main(){ //输入字符串 char str[10]原创 2016-06-18 21:51:10 · 286 阅读 · 0 评论 -
丑数35
题目描述:我们把只包含因子2、3和5的数称作丑数(UglyNumber)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它含因子7。习惯上我们把1当作第一个丑数。 测试用例:int main(){ //要求的第n个丑数 int n = 1500; //第n个丑数为 int result = UglyNumber(n); //输出结原创 2016-06-18 17:26:41 · 425 阅读 · 0 评论 -
把数组排成最小的数34
题目描述:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3, 32, 321},则打印出这3个数字能排成的最小数字321323。解题思路:考虑两个数拼接可能会溢出,使用字符串解决大数问题。测试用例:int main(){ //输入数组 int arr[3] = {3, 32, 321}; //数组中的数字组合排列原创 2016-06-18 17:26:06 · 237 阅读 · 0 评论 -
从1到n整数中1出现的次数33
题目描述:输入一个整数n,求从1到n这n个整数的十进制表示中1 出现的次数。例如输入12,从1到12这些整数中它含1的数字有1,10,11和12,1一共出现了5次。解题思路:解法一:循环依次对每一个1~n之间的数求模,若为模为1则计次,最终返回1出现的次数。复杂度高O(n*longN).解法二:从数字规律着手明显提高时间效率的解法O(logn)测试用例:int main(){ //输原创 2016-06-18 15:38:55 · 485 阅读 · 0 评论 -
连续子数组的最大和32
题目描述:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。如输入的数组为{1, -2, 3, 10, -4, 7, 2, -5},和最大的子数组为{3, 10, -4, 7, 2},因此输出为该子树组的和为18。解题思路:举例分析数组的规律从头到尾累加数组中的每个数字,设置两个临时变量,当前累加的和及最大和。原创 2016-06-18 11:51:01 · 323 阅读 · 0 评论 -
最小的K个数31
题目描述:输入n个整数,找出其中最小的k个数。例如输入{ 4, 5, 1, 6, 2, 7, 3, 8} 这8个数字,则最小的4个数字是1, 2, 3, 4。解题思路:O(nlogk)的算法,特别适合做海量数据使用STL中的multiset先从vector中依次取出k个数存入multiset然后将后面的vector元素与multiset(使用红黑树实现,begin既是k个数中最大者)的首元素原创 2016-06-18 10:55:50 · 377 阅读 · 0 评论 -
数组中出现次数超过一半的数字30
题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.解题思路:解法一:基于Partition, O(n)时间解法二:根据数组特点找出O(n)的算法 a.数组中一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出原创 2016-06-18 10:41:09 · 329 阅读 · 0 评论 -
字符串的排列29
题目描述:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cba、和cab。解题思路:把这个复杂的问题分解成小问题先把一个字符串看成两部分组成:第一部分为它们的第一个字符,第二部分是后面所有的字符。而求整个字符串的排列,可以看成两步: 第一步:求所有可能出现在第一个位置的字符,即把第一个字符原创 2016-06-18 09:08:48 · 450 阅读 · 0 评论 -
二叉搜索树与双向链表28
题目描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。即:即将一棵二叉搜索树转换成双向链表。解题思路:二叉搜索树是排序的,双向链表前后都有指针。在转换成双向链表时,原先指向左子节点的指针调整为链表中指向前一节点的指针, 原先指向右子节点的指针调整为链表中指向后一节点指针。中序遍历,递归转换 二叉树节点定义://二叉树结点原创 2016-06-17 22:15:22 · 304 阅读 · 0 评论 -
复杂链表的复制27
题目描述:请实现函数ComplexListNode *Clone(ComplexListNode *pHead); 复制一个复杂链表。在复杂链表中,每个节点除了有一个m_Next指针指向下一个节点外,还有一个s_Sibling指向链表中的任意节点或者NULL。复杂链表节点定义如下://复杂链表的定义struct ComplexListNode{ int m_value; //节点存储的值原创 2016-06-16 19:10:51 · 300 阅读 · 0 评论 -
数组中的逆序对37
题目描述:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如在数组{7, 5, 6, 4,}中,一共存在5个逆序对,分别是(7,6)、(7,5)、(7,4)、(6,4)、(5,4)。解题思路:以上面的数组为例我们先把数组分解成两个长度为2的子数组。再把这两个子数组分别拆分成两个长度为1的子数组接下来一边合并相邻的数组原创 2016-06-19 09:09:46 · 542 阅读 · 0 评论 -
两个链表的第一个公共节点38
题目描述:输入两个链表,找出它们的第一个公共节点。链表节点定义如下://单向链表的节点定义struct ListNode{ int m_value; //节点存储的值 ListNode *m_next; //节点指针 void show(); //打印所有节点值};解题思路:由于是单向链表,只能从头节点开始顺序遍历首先遍历两个链表得到它们的长度,a.知道哪个链表长,b.知道长原创 2016-06-19 10:00:34 · 436 阅读 · 0 评论 -
数字在排序数组中出现的次数39
题目描述:统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4.解题思路:由于是排序,利用二分查找找到第一个k的位置找到最后一个k的位置找到第一个k和最后一个k之后,就可计算出k在数组中出现的次数。测试用例:int main(){ //输入数组 int arr[8] = {1,原创 2016-06-19 10:33:41 · 414 阅读 · 0 评论 -
不能被继承的类49
题目描述:用C++设计一个不能被继承的类,在C#中定义了关键字sealed,被sealed修饰的类不能被继承。在JAVA中同样也有关键字final表示一个类型不能被继承。解法一:把构造函数设为私有成员在C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。定义公有的静态函数来创建和释放类的实例。此方法缺点:只能得到位于堆上的实例,而得不到位于栈上的实例。原创 2016-06-22 20:52:25 · 592 阅读 · 0 评论 -
不用加减乘除做加法48
题目描述:写一个函数,求两个整数之和,要求在函数体内不能使用+、-、*、/ 四则运算符号。解题思路:使用位运算;第一步相加不考虑进位,0加0、1加1的结果都是0;0加1、1加0的结果都是1,所以第一步是异或的结果;第二步考虑进位,0加0、0加1、1加0都不产生进位;只有1加1会向前产生一个进位。此时可以想象成是两个数先位与运算,然后再做移1位。最后将前两个步骤的结果相加。但仍然要重复前面的原创 2016-06-22 19:32:00 · 487 阅读 · 0 评论 -
求1+2+...+n47
发散思维能力: 发散思维的特点是思维活动的多向性和变通性,也就是我们在思考问题时注重运用多思路、多方案、多途径地解决问题。对于同一个问题,我们可以从不同的方向、侧面和层次,采用探索、转换、迁移、组合和分解等方法,提出多种创新的解法。题目描述:求1+2+…+n,要求不能使用乘除法,for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。解题思路:公式n(n+原创 2016-06-22 19:03:24 · 333 阅读 · 0 评论 -
圆圈中最后剩下的数字46
**题目描述:**0,1,…,n这几个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。例如,0,1,2,3,4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前四个数字依次是2,0,4,1,因此最后剩下的数字是3。本题就是有名的约瑟夫环问题。 测试用例:int main(){ //测试 std::cout << Las原创 2016-06-20 22:16:00 · 603 阅读 · 0 评论 -
扑克牌的顺子45
题目描述:从扑克牌中随机抽取5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字(用0表示)。解题思路:第一步:将抽取的5张牌放在5个数字组成的数组,然后将其排序。第二步:判断这5个数字是不是连续的,可以用0去补满数组中的空缺。统计数组中0的个数;统计排序之后的数组中相邻数字之间的空缺总数。如果空缺的总数小于或原创 2016-06-20 19:09:49 · 872 阅读 · 0 评论 -
n个骰子的点数44
抽象建模的能力建模的第一步是选择合理的数据结构来表述问题。即建立模型。建模的第二步是分析模型中的内在规律,并用编程语言表示这种规律。我们只有对现实问题进行深入细致的观察分析之后,才能找到模型中的规律,才有可能编程解决问题。题目描述:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。解题思路:n个骰子的点数和的最小值为n,最大值为6n;n个骰子的原创 2016-06-19 16:59:12 · 466 阅读 · 0 评论 -
翻转单词顺序 VS 左旋转字符串43
题目一(翻转单词顺序):输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串”I am a student.”则输出”student. a am I”。解题思路:首先翻转整个字符串再翻转句子中的每个单词测试用例:int main(){ //输入字符串 char str[16] = "I am a student.原创 2016-06-19 13:47:29 · 574 阅读 · 0 评论 -
和为s的两个数字 VS 和为s的连续正数序列42
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。例如输入数组{1, 2, 4, 7, 11, 15}和数字15。由于4 + 11 = 15,因此输出4和11。解题思路:先在数组中选择两个数(第一个数和最后一个数),如果它们的和等于输入的s,那么就找到了数字。如果小于s,由于数组是递增排序的,所以可以选择将第一个数字原创 2016-06-19 11:52:24 · 398 阅读 · 0 评论 -
数组中只出现一次的数字41
题目描述:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。例如{2,4,3,6,3,2,5,5},因为只有4,6这两个数次出现一次,所以输出4和6。解题思路:数组里有两个数字只出现一次,其他数字都出现两次。异或性质:任何一个数字异或它自己都等于0.将数组拆分成两个子数组,使得每个子数组包含一个只出现一次原创 2016-06-19 11:16:32 · 565 阅读 · 0 评论 -
二叉树的深度及平衡二叉树40
题目一:输入一颗二叉树的根节点,求该树的深度。从根节点直到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径长度为树的深度。 二叉树结点定义:struct BinTreeNode{ int m_value; BinTreeNode *left; BinTreeNode *right; //创建根节点,值为e BinTreeNode* createRoot(int e原创 2016-06-19 11:02:44 · 796 阅读 · 0 评论 -
二叉树中和为某一值的路径26
题目描述:输入一颗二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。二叉树结点定义://二叉树定义struct BinTreeNode{ int m_value; BinTreeNode *left; BinTreeNode *right; //创建根节点,值为e BinTreeNode* create原创 2016-06-14 19:17:59 · 261 阅读 · 0 评论 -
从尾到头打印链表(单向链表)5
链表是一种动态数据结构,创建链表时,无需知道链表的长度,当插入一个节点时,我们只需为新节点分配内存,然后调整指针的指向来确保新节点被链接到链表当中。 单向链表的节点定义:struct ListNode{ int m_value; //节点存储的值 ListNode *m_next; //节点指针 void show(); //打印所有节点值};void ListNode::sho原创 2016-05-18 22:58:14 · 406 阅读 · 0 评论 -
数值的整数次方15
1.代码质量:资源回收、异常状况、对“正常值”进行的处理、功能错误、边界情况。 2.规范的代码:清晰的书写、布局、命名 3.关键是在写代码之前形成清晰的思路,并能把思路用编程语言清楚地写出来。 4.单元测试的设计:负面测试(即错误的输入)、功能测试、边界测试。 5.三种错误处理的方法,各有优缺点: a.函数返回值。优:和系统一致。缺:不能方便的计算结果。 b.全局变量。优原创 2016-05-29 10:26:31 · 439 阅读 · 0 评论 -
打印1到最大的n位数16
解决一个问题时若需要表达一个大数,最容易的方法是使用字符串或数组。题目描述:输入数字n,按顺序打印出从1到最大的n位十进制数。比如,输入3,则打印出1、2、3、4一直到最大的3位数999。解题思路:考虑最大数是否溢出字符串解决大数问题测试用例:int main(){ //打印数字的位数 int bit = 3; //可尝试各种解法 Rprint1ToMaxOfN原创 2016-05-30 06:57:59 · 392 阅读 · 0 评论 -
反转链表17
题目描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。链表节点的定义如下:struct ListNode{ int m_value; //节点存储的值 ListNode *m_next; //节点指针 void show(); //打印所有节点值};解题思路:需要三个指针,当前遍历的节点,它的前一个节点以及它的后一个节点,防止链表断开。测试用例:int原创 2016-05-30 20:27:57 · 339 阅读 · 0 评论 -
合并两个排序的链表18
题目描述:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然按照递增排序。如输入链表1{1,3,5};链表2{2,4,6,8};合并后,链表3{1,2,3,4,5,6,7,8}。链表定义://单向链表的节点定义struct ListNode{ int m_value; //节点存储的值 ListNode *m_next; //节点指针 void show(); //打印所原创 2016-05-30 21:43:41 · 282 阅读 · 0 评论 -
顺时针打印矩阵21
题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如,输入以下矩阵: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 则打印出:1, 2, 3, 4, 5, 0, 5, 0, 5, 4, 3, 2, 1, 6, 1, 6, 7, 8, 9, 4, 9, 8, 7, 2, 3解题思路:将复杂的问题分解成若干个简单原创 2016-06-06 22:17:12 · 292 阅读 · 0 评论 -
二叉树的镜像20
画图让抽象问题形象化:画图是用来帮助自己分析、推理的常用手段,当问题比较抽象时,不如画出一些与题目相关的图形,辅助自己观察和思考。图形能使抽象的问题具体化、形象化。空想未必能找到题目中隐含的规律和特点。题目描述:请完成一个函数,输入一个二叉树,该函数输出它的镜像。二叉树结点定义:struct BinTreeNode{ int m_value; BinTreeNode *left; Bin原创 2016-06-06 19:15:24 · 404 阅读 · 0 评论 -
树的子结构19
题目描述:输入两棵二叉树A和B,判断B是不是A的子结构。二叉树结点的定义如下://二叉树的定义struct BinTreeNode{ int m_value; BinTreeNode *left; BinTreeNode *right; //创建根节点,值为e BinTreeNode* createRoot(int e); //将e作为当前结点的左孩子值插入 void原创 2016-05-31 22:10:26 · 308 阅读 · 0 评论 -
包含min函数的栈22
举例让抽象问题具体化:当一眼看不出问题中隐藏的规律的时候,我们可以试着用一两个具体的例子模拟操作的过程,找到抽象的规律。具体的例子可以帮助我们解释清楚算法思路。算法通常是很抽象的,用语言不容易表述的很清楚。所以可以考虑举具体的例子,阐述算法是怎么一步步处理这个例子的。题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度是原创 2016-06-07 20:30:31 · 282 阅读 · 0 评论 -
栈的压入、弹出序列23
题目描述:输入两个整数序列,第一序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压栈序列,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。解题思路:建立一个辅助栈,将输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从栈中弹出数字。如何判断一个序原创 2016-06-12 19:03:41 · 302 阅读 · 0 评论 -
从上往下打印二叉树24
题目描述:从上往下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。即层次遍历。 二叉树结点定义:struct BinTreeNode{ int m_value; BinTreeNode *left; BinTreeNode *right; //创建根节点,值为e BinTreeNode* createRoot(int e); //将e作为当前结点的左孩子值插原创 2016-06-13 20:32:07 · 256 阅读 · 0 评论 -
调整数组顺序使奇数位于偶数前面14
题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分。解题思路:O(n^2)的方法:从前向后逐一扫描交换。基本解法前后两个指针,移动交换,直到p2刚好在p1前面一个位置,代表后面的都是偶数,前半部分都是奇数。可扩展的解法使用一个谓词(bool)函数,判断符合什么类型的条件,主体框架相同。如:判断奇偶、判断正负数等等。测试用例:int main(){原创 2016-05-26 22:46:52 · 350 阅读 · 0 评论 -
在O(1)时间删除链表节点13
题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。链表节点与函数定义如下://单向链表的节点定义struct ListNode{ int m_value; //节点存储的值 ListNode *m_next; //节点指针 void show(); //打印所有节点值};解题思路:如果从头至尾找到节点并删除需要O(n)时间。我们直接把要删除节点的原创 2016-05-26 20:04:06 · 601 阅读 · 0 评论 -
位运算:二进制中1的个数12
位运算:是把数字用二进制表示之后,对每一次是0或1的运算。乘除效率低,实际编程中尽可能的用移位运算代替乘除法。世界上有10中人,一种人知道二进制,而另一种人不知道二进制……五种位运算:与、或、异或、左移和右移,分别对应&、 |、 ^、<<、 >>。 异或:相同为0, 相异为1。左移运算符m左移n,表示把m左移n位, 最左边的n位将被丢弃。右移要复杂些,右移时处理最左边位: 如果数字是一个无符号数值原创 2016-05-24 20:25:51 · 896 阅读 · 0 评论 -
替换字符串中的空格4
字符串是由若干字符组成的序列。 1.C/C++中每个字符串都以’\0’作为结尾; 2.为了节省内存,C/C++中把常量字符串放到单独的一个内存区域。当几个指针赋值给相同的常量字符串时,它们实际上指向相同的地址。 例:char *str1 = "hello";char *str2 = "hello";//str1与str2是指针,所以它们地址相同。"hello"是常量字符串,它在内存中只有一原创 2016-05-18 19:48:49 · 439 阅读 · 0 评论