算法题
Findway_
我的博客:lhgaaa.github.io
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3, 32, 321}, 则打印出这3个数字能排成的最小数字321323.思路: 将数组中的每个数字按照某种规则排序,排序之后得到的序列就是这个数组所能排成的最小数字。 需要自定义一个排序的规则,也即就是重写自定义一个compare函数或者仿函数。 排序的规则: 给定两个整数,原创 2017-08-08 11:14:24 · 342 阅读 · 0 评论 -
字符串的排列(草稿)
题目描述输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。思路: 求整个字符串的排列,可以看成两步: (1).首先求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。原创 2017-06-06 17:54:16 · 278 阅读 · 0 评论 -
最小的k个数
题目描述输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。思路一:基于partition函数的算法,时间复杂度可达到O(n)class Solution{ vector<int> GetLeastNumbers_Solution( vector<int> input, int k ) { if (原创 2017-08-06 10:09:27 · 295 阅读 · 0 评论 -
把字符串转换为整数
题目:编写一个StrToInt函数实现atoi库函数的功能。参考的函数接口如下:int StrToInt( char *string );分析: 编写库函数时要充分考虑到各种情况,对于这道题,到考虑到一下几点:1.传入的字符串是否为NULL或者空字符串。2.传入的字符串是否为合法数字(存不存在其他非法字符)。3.字符串中符号位的处理。4.转换失败的标示。5.字符串表示的数字是否超出表原创 2017-08-13 16:43:11 · 240 阅读 · 0 评论 -
不能被继承的类
题目:用C++设计一个不能被继承的类。分析: 一个类被继承后,在生成派生类对象时,派生类会主动调用父类的构造函数,所以如果父类的构造函数被设置成私有时,派生类的对象就无法构建。一、直接将构造函数设为私有函数class SealedClass{public: static SealedClass* GetInstance() { return new Seal原创 2017-08-13 15:17:30 · 340 阅读 · 0 评论 -
不用加减乘除做加法
题目:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、×、/四则运算符号。分析: 使用二进制位运算对加法进行模拟class Solution{public: int Add( int num1, int num2 ) { int sum, carry; do { sum = num1 ^ nu原创 2017-08-13 15:01:40 · 186 阅读 · 0 评论 -
求1+2+....+n
题目:求1+2+...+n,要求不能使用乘除法、for、while、if、else、switch、case、等关键字及条件判断语句(A?B:C)声称可以考察发散性思维的题目:解法:1.构造函数2.虚函数3.函数指针4.模板类型1.构造函数: 在构造函数中累加类中的静态成员变量,然后构造n个该类的对象。class Temp{public: Temp() { ++N; Sum原创 2017-08-13 12:07:28 · 580 阅读 · 0 评论 -
圆圈中最后剩下的数字
题目:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求这个圆圈里剩下的最后一个数字。分析: 1.利用环形链表模拟圆圈求解。 2.利用删除之后的规律求解。环形链表:class Solution{public: int LastRemaining_Soultion( int n, int m ) { if ( n <原创 2017-08-11 20:51:12 · 215 阅读 · 0 评论 -
扑克牌的顺子
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大王、小王可以看成任意数字。分析: 将大小王看成0,将数组排序,统计数组中空缺的数字个数,如果个数小于大小王的个数,就可以构成顺子,如果数组中有重复的非0数字,就不能构成顺子。可以借助哈希表对上面稍作了一点改变的我的思路:class Solution {pu原创 2017-08-11 16:09:47 · 321 阅读 · 0 评论 -
树中两个结点的最低公共祖先
题目:输入两个树节点,求它们的最低公共祖先。分析: 这道题对于不同的树有不同的解法,分为以下几类:1.二叉搜索树。2.普通树,但结点中有指向父节点的指针。3.普通数。1.二叉搜索树二叉搜索树中结点的左孩子值都小于结点的值,结点的右孩子值都大于结点的值。两个树结点的最低公共祖先肯定是将这两个树结点分隔到了不同的两个子树中,所以最低公共祖先的值肯定介于这两个树结点之间。从上往下遍历二叉搜索树原创 2017-08-14 11:02:26 · 381 阅读 · 0 评论 -
数组中重复的数字
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。分析: 有两个解决方法:1.排序之后再找重复数字2.利用哈希表3.根据数组特点1.排序之后再找重复数字时间复杂度为O(原创 2017-08-14 15:25:37 · 240 阅读 · 0 评论 -
二叉树的下一个结点
题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。分析: 例: 1.如果这个结点有右子树,那下一个结点就是右子树的最左结点,例如结点e。 2.如果这个结点没有右子树,但他是父结点的左孩子,那么它的下一个结点就是父结点,例如结点d。 3.如果这个结点没有右子树,并且他是父结点的右孩子,那么就要一直上原创 2017-08-14 21:18:58 · 192 阅读 · 0 评论 -
删除链表中重复的结点
题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。分析: 常规方法删除class Solution{public: ListNode* deleteDuplication( ListNode* pHead ) { if ( pHea原创 2017-08-14 20:33:18 · 182 阅读 · 0 评论 -
位运算
位运算中设计到的操作有:与、或、非、异或、左移、右移。题目一:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数,例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2。分析: 1.将给定的整数右移,并且判断每一次右移之后最低位是否为1. 2.设置一个flag,每次将flag左移,判断给定的整数每一位是否为1. 3.将一个数与它减一相与,会将这个数最右边的1变为0.原创 2017-08-21 19:49:24 · 233 阅读 · 0 评论 -
链表中环的入口点
题目:一个链表中包含环,请找出该链表的环的入口结点。分析: 分两步: 1.利用两个指针知道链表的环中的结点数。 2.利用两个指针找到入口结点。class Solution{public: ListNode* EntryNodeOfLoop( ListNode* pHead ) { ListNode* meetingNode = MeetingNode( p原创 2017-08-14 17:43:03 · 318 阅读 · 0 评论 -
字符流中第一个不重复的字符
题目:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。输出描述:如果当前字符流没有存在出现一次的字符,返回#字符。分析: 使用哈希表class Solution{public: Solution() : index(原创 2017-08-14 17:20:21 · 216 阅读 · 0 评论 -
表示数值的字符串
题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。class Solution{public: bool isNumeric( char* string ) {原创 2017-08-14 16:51:30 · 208 阅读 · 0 评论 -
正则表达式匹配
题目:请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。class Solution {public: bool match(char* s原创 2017-08-14 16:37:36 · 243 阅读 · 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]。不能使用除法。分析: 1.如果可以使用除法,最直观的方法就是使用连乘来得到B[i]。这样的方法时间复杂度为O(n2). 2.结合矩阵知识来解决这个问题。2.结合矩阵知识时间复杂度为O(n)的算法。cl原创 2017-08-14 16:04:56 · 209 阅读 · 0 评论 -
数组中出现次数超过一半的数字
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。思路一:排序如果数组中有出现次数超过一半的数字,那么排序之后取数组中间元素肯定就是数组中超过一半的数字。class Solution {public: int MoreTh原创 2017-06-05 10:17:37 · 306 阅读 · 0 评论 -
翻转单词顺序VS左旋转字符串
题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串“I am a student.”,则输出“student. a am I”。分析: 这个问题可以分成两个过程来解决: 1.翻转整个句子,翻转结果为.tneduts a ma I 2.再将里面的每个单词翻转一次,结果为student. a am Iclass Sol原创 2017-08-11 11:06:11 · 271 阅读 · 0 评论 -
数组中的逆序对
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。分析: 一、首先,最直观的算法就是我们遍历数组中的每个数字,在遍历到一个数字时,把这个数字和之后的数字作比较得出结果,这种算法的时间复杂度为O(n2). 二、要求出逆序对的个数,我们可以换一种思路,如果我们将数组按照从小到大的顺序排序,那么这个数组的逆序对就为0,假原创 2017-08-09 14:28:24 · 335 阅读 · 0 评论 -
序列化二叉树
题目:请实现两个函数,分别用来序列化和反序列化二叉树class Solution {private: TreeNode* decode(char *&str) { if(*str=='#'){ str++; return NULL; } int num = 0; while(*原创 2017-08-16 15:45:57 · 229 阅读 · 0 评论 -
第一个只出现一次的字符
题目:在字符串中找出第一个只出现一次的字符。如输入“ababbdeff”,则输出‘b’。将字符串遍历两次,第一次遍历会将字符串中各字符的出现次数统计到哈希表中,第二次遍历,找到字符串中第一个只出现一次的字符。class Solution{public: int FirstNotRepeatingChar( string str ) { int len = st原创 2017-08-09 10:23:39 · 234 阅读 · 0 评论 -
按之字形顺序打印二叉树
题目:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。分析: 使用两个栈。struct TreeNode{ int val; struct TreeNode *left; struct TreeNode *right; TreeNode( int x ) :原创 2017-08-16 11:13:28 · 205 阅读 · 0 评论 -
对称的二叉树
题目:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。分析: 通常的树的遍历算法都是先遍历访问左子树,再访问右子树,我们设计一种新的遍历算法,先访问右子树,再访问左子树。并且我们需要考虑到空结点。struct TreeNode{ int val; struct TreeNode *left; struct T原创 2017-08-16 10:29:40 · 224 阅读 · 0 评论 -
丑数
题目:我们把只包含因子2,3,和5的数称为丑数(ugly Number)。求按从小到大的顺序的第1500个数。例如6、8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做第一个丑数。一、暴力解法,不推荐遍历并且判断该数是不是丑数。class Solution{public: int GetUglyNumber_Solution( int index ) {原创 2017-08-08 15:06:44 · 188 阅读 · 0 评论 -
连续子数组的最大和
题目:输入一个整型数组,数组里有正数也有负数。数组中有一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。思路一:根据数组规律int FindGreatestSumOfSubArray( vector<int> array ) { int curSum = 0; int greatestSum = 0x80000000;原创 2017-08-07 15:14:01 · 172 阅读 · 0 评论 -
从1到N整数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11,12,1一共出现了5次。一、暴力求解,不被推荐class Solution{public: int NumberOf1Between1AndN( unsigned int n ) { int number = 0;原创 2017-08-08 10:59:50 · 198 阅读 · 0 评论 -
两个链表的第一个公共结点
题目:输入两个链表,找出它们的第一个公共结点。链表结点定义如下:struct ListNode{ int m_nkey; ListNode* m_pNext;};分析:如果两个单链表有公共结点,那么公共结点之后的结点全都是是两个链表的公共结点。我们可以从后往前遍历两个单链表,直到遍历到的结点不同为止。 一、使用栈可以实现单链表的反向遍历。class Soluti原创 2017-08-09 15:37:38 · 197 阅读 · 0 评论 -
数据流中的中位数
题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。class Solution{public: void Insert( int num ) { if ( ((min.size()+max.size()) & 1) ==原创 2017-08-16 19:49:06 · 185 阅读 · 0 评论 -
反转链表
题目:输入一个链表,反转链表后,输出链表的所有元素。struct ListNode{ int value; ListNode *next;};void ReverseList( ListNode** pHead ){ if ( pHead == NULL || *pHead == NULL || (*pHead)->next == NULL )原创 2017-08-18 10:20:22 · 189 阅读 · 0 评论 -
矩阵中的路径
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵原创 2017-08-17 15:27:59 · 193 阅读 · 0 评论 -
二叉搜索树的第k个结点
题目:给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 3 7 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。分析: 中序遍历二叉树。class Solution{public: TreeNode* KthNode( TreeNode* pRoot, int k ) { if ( pRoot == NULL || k == 0 )原创 2017-08-16 19:47:30 · 330 阅读 · 0 评论 -
和为s的两个数字VS和为s的连续正数序列
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。要求O(n)。分析: 增加两个指针,分别指向数组的第一个和最后一个元素,如果指针指向的两个元素之和大于s,后面的指针向前移动,如果指针指向的两个元素之和小于s,则前面的指针向后移动。只需要遍历数组一次,所以时间复杂度为O(n)。class Solution{pu原创 2017-08-10 11:03:22 · 541 阅读 · 0 评论 -
数组中出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。分析: 我们可以先考虑一个稍微简单点的情况,一个整型数组里除了一个数字之外,其他的数字都出现了两次。这是上面题目的一个简化版本。我们只要能解决这个问题了,然后将上面题目中的数组按照某种规则分别分成两个只有一个数字出现一次的数组,就可以解决上面的题目。原创 2017-08-09 21:06:37 · 266 阅读 · 0 评论 -
二叉树的深度
题目一:输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。关键词:二叉树的遍历class Solution{public: int treeDepth( TreeNode* pRoot ) { if ( pRoot == NULL ) return 0;原创 2017-08-09 20:26:43 · 221 阅读 · 0 评论 -
数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。关键词: 二分查找class Solution{public: int GetNumberOfK( vector<int> data, int k ) { int number = 0;原创 2017-08-09 19:58:12 · 195 阅读 · 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,[4,2,6],2,5,1}原创 2017-08-16 20:43:14 · 214 阅读 · 0 评论 -
机器人的运动范围
题目:地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?class Solution{public:原创 2017-08-18 09:37:50 · 210 阅读 · 0 评论
分享