算法题
moses1213
积跬步,至千里;积小流,成江海!
展开
-
自己实现的高效的指数函数
传统的使用递归实现的指数函数是非常低效的,这种算法所用的乘法次数为logN,其中N为指数。#includeint iseven(int a){ if(a % 2 == 0) return 1; else return 0;}long int newpow(long int x, unsigned int N){ if(N ==原创 2015-02-03 19:34:12 · 752 阅读 · 0 评论 -
C++中的变位词问题
题目:给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。这道题目是个典型的变位词问题,即一个字符串是否是另一个字符串的乱序版本,解题思路很多,下面总结三种方法,有其他方法还会更新。解法一:最直观的想法就是对两个字符串排序,然后比较两个字符串。这里利用STL里的sort进行排序,头文件。int cmp(char a, char b){ return原创 2016-07-15 20:35:01 · 1104 阅读 · 0 评论 -
编程珠玑第三章—习题4(日期问题)
问题1:给定两个日期,计算两者之间的天数。解答:可以现将月和日换算成该年的第多少天,用后者减去前者,然后年份差距乘以365,同时考虑到两个年份之间闰年的个数,如果闰年个数为n,则最后结果再加上n.#include typedef struct{ int year; int month; int day;}date;//日期在相应年份中的编号int transform(da原创 2015-11-01 21:32:10 · 567 阅读 · 0 评论 -
素数生成算法
素数生成问题,解法主要分为试除法和筛选法两种,筛选法里又有很多算法,这里各实现一种比较方便且容易理解的方法,用来生成1到n之间的素数。1.试除法bool IsPrime(int num){ if(num < 2) return false; if(num == 2) return true; if(num % 2 == 0) return fals原创 2016-07-30 21:13:25 · 2602 阅读 · 0 评论 -
给定因子求第K个数
题目:有些数的素因子只有3,5,7,请设计一个算法,找出其中第K个数。思路:因为只存在素因子3,5,7,所以这些数具有这样的形式:3^x * 5^y * 7^z。假设当前已经生成了一些数,那么产生下一个数应该还是拿3或5或7乘以已经生成的数中的某个数。这一步可以在生成一个数的时候预先处理,每生成一个数x,同时将3*x,5*x,7*x放入预备队列,生成下一个数的时候总是从预备队列里找出一个最小的原创 2016-08-05 12:21:04 · 1230 阅读 · 0 评论 -
打印n对括号的全部有效组合
这道题最基本的思路是求出n对括号的全排列,然后对每种排列方式判定是否有效。判定方法如下:bool IsMatch(string& str){ if(str.size() % 2 != 0) return false; int result = 0; for(string::iterator it = str.begin(); it != str.end(); ++it) {原创 2016-08-06 19:16:42 · 1707 阅读 · 0 评论 -
硬币的表示法
题目:给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。思路:这个问题真的非常有意思,需要用到递归的思想。假设现在有50分,求它的表示法。(1)50分可以用0个25分硬币,这下剩下的问题就是50分用10分、5分和1分表示;(2)50分用1个25分表示,问题转化为25分用10分、5分和1分表示;(3)50分用2个25分表示,这时候返回1。所以可以看到这是一个原创 2016-08-07 17:37:10 · 658 阅读 · 3 评论 -
八皇后问题的两种解法
八皇后问题,即八个皇后放在8*8的格子上,要求每个皇后不同行、不同列,也不再对角线上。解法一:全排列解法。八个皇后不同行,那么假设存在一个数组大小为8,数组下标代表行,0~7都会被占满,数组每个下标位置上的值代表当前皇后的列,即下标值代表皇后的行,数组值代表列。下标0~7肯定会不同,如果以0~7初始化数组,那么列也会完全不同。那么列的排列就是0~7八个数的全排列问题,剩下的就是要判断是不是在对原创 2016-08-07 23:32:08 · 1765 阅读 · 7 评论 -
美团点评编程题
1.输入一个数组nums,要求返回一个新的数组count,count的i位置上放置的是nums[i]右边有多少比它小的数。例如输入: 1 2 3 4输出:0 0 0 0 这道题从右边倒着数比较好,可惜当时没有考虑到相邻的数相等的情况,美团点评的题目没有自己的测试用例,需要用户自己考虑到所有可能的情况……#include #include using namespace std;原创 2016-09-09 21:26:17 · 1527 阅读 · 0 评论 -
走格子问题
6×9的的方格中,起点的左下角,终点在右上角,从起点到终点,只能从下向上,从左向右走,问一共有多少种不同的走法。A. 4200B. 5005C. 1005D. 以上都不正确这原本是道选择题,答案选B。已选择题的思路的来解决这道问题,假设左下角坐标为(0,0),那么右上角坐标为(6,9)。从左下角走到右上角,横向要走9步,纵向走6步,不管采用哪种方式横向和纵向走的步原创 2016-08-09 17:21:08 · 2575 阅读 · 0 评论 -
腾讯模拟笔试
编程题:有蛇形矩阵,比如宽为3的时候为 1 2 3 8 9 4 7 6 5,宽为4的原创 2016-09-02 10:13:38 · 806 阅读 · 0 评论 -
KMP算法详解
原文出处:http://billhoo.blog.51cto.com/2337751/411486/【KMP算法简介】 KMP算法是一种改进后的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。通过一个辅助函数实现跳过扫描不必要的目标串字符,以达到优化转载 2016-07-26 16:57:31 · 332 阅读 · 0 评论 -
大小为n的搜索树的个数
题目:给出一个数字n,假设用一棵搜索树来存储1~n,问这样的搜索树有多少个?例如,当n=3时,有5个独立的搜索树。思路:有数字1,2,3,…,m,…n-1,n-2,那么当数字m作为搜索树的根时,左边的数字必须在它的左子树上。m的左边有m-1个数字,显然这是一个1~m-1的搜索树个数问题。m的右边有n-m个数,虽然数字是从m+1到n,但是实际上等同于1~n-m的搜索树个数问题。有个这个基原创 2016-05-23 22:06:25 · 417 阅读 · 0 评论 -
数组中两个数相减(相加)的最大值
题目:有一个数组,找出数组中前面的数减去后面的数的最大值。例如数组{9,1,7,18,3,-2,20,4,0,5},最大值是18-(-2)或者20-0。解法一:把数组分为左右两个部分,相减最大的两个数可能产生于左半部分,右半部分,或者横跨左右两个部分,最大值为这三种情况中数值最大的那个。对于两个数位于左右两部分的情况,最大的结果应该是左半部分的最大值减右半部分的最小值;左半部分和右半部分又可以原创 2016-05-20 11:17:07 · 9754 阅读 · 0 评论 -
括号匹配程序
如果左括号总能找到和它对应的右括号,那么我们就称为匹配。存在多余的右括号或者左括号都不匹配。#include#include#include#define CAPACITY 50typedef struct stack{ int top; char arr[CAPACITY];}stack;void initStack(stack *st){ st =原创 2015-02-03 19:37:56 · 697 阅读 · 0 评论 -
逆波兰计算器改进版
前面有写过逆波兰计算器,那时候只能进行个位数计算,现在采用分隔符的办法实现多位数即小数的计算,即在每个数字或者运算符或括号之后加上空格,来确定这个数是否输入结束。逆波兰式保存在一个数组里,然后按照逆波兰计算规则就可以了,注意要使用atof转换。下面是代码部分。#include#include#include#define CAPACITY 50typedef struct stack{原创 2015-03-09 20:36:06 · 454 阅读 · 0 评论 -
求最大公约数(欧几里得算法)
原理见百度百科:欧几里得算法int gcd(int a, int b){ if(a < b) swap(a, b); return b == 0 ? a : gcd(b, a % b);}用于编程珠玑第二章的向量旋转问题,重新写这个程序:#include #include using namespace std;void rotate(string &str, in原创 2015-10-24 20:42:05 · 419 阅读 · 0 评论 -
消除重复单词
sort函数在头文件中。void elimDups(vector &vec){ sort(vec.begin(), vec.end()); auto end_unique = unique(vec.begin(), vec.end()); vec.erase(end_unique, vec.end());}原创 2015-11-12 15:24:49 · 1197 阅读 · 0 评论 -
Top K算法和寻找第K个最小的数
关于Top K算法和寻找第K个最小的数这种经典问题网上已经说的很详细了,不过毕竟不是自己的,这里自己总结一下,而且这两个问题又稍稍有点区别。1.Top K算法:即寻找一列数中K个最小值或K个最大值,这里仅以寻找K个最小值为例(算法类似)。(1)排序算法:最直观的算法就是给整列数排序,然后取前K个数。这里主要对各种排序算法的时间复杂度进行分析:插入排序:由于嵌套循环的每一次迭代都花费N次原创 2016-01-19 19:34:46 · 4554 阅读 · 0 评论 -
最大子序列和问题
问题:任意给定一序列,求解连续子序列的最大和。算法一:最简单粗暴的解法,把所有可能的情况简单遍历。如果序列长度为n,设和最大的子序列为[i,j],i从0到n遍历,j从i到n遍历,和为数组元素下标为i~j的累加,时间复杂度为O(n^3).//立方算法int MaxSubSepSum(int *a, int n){ int MaxSum = 0; for(int i = 0原创 2016-01-11 21:19:58 · 361 阅读 · 0 评论 -
字符串的全排列非递归实现算法
题目类似剑指offer的第28题,这里在粘贴一下:题目:输入一个字符串,打印出该字符串中字符放入所有排列。例如输入字符串abc,则打印出字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。递归的实现算法:http://blog.csdn.net/moses1213/article/details/51055692这里用非递归的算法实现:假设有字符串p1原创 2016-04-04 20:30:16 · 1433 阅读 · 0 评论 -
编程珠玑第二章习题—向量的旋转
书中讲到两种方法,“杂技”交换和“块交换”,注意形参一定要传引用!“杂技”交换法:void rotate1(vector &vec, int i){ set s; int N = vec.size(); int start = 0; while(s.size() != N) { int n = 0; int tmp = vec[start]; while(((n+1原创 2015-10-24 17:08:18 · 439 阅读 · 0 评论 -
重新认识二分查找算法
自己也曾写过二分查找算法,可是认识却有点模糊,或者说对算法的流程理解的并不是很透彻。《编程珠玑》里提到用循环不变式的三个性质来检验算法的正确性,即:1.初始化:保证循环开始前初始条件是正确的。2.保持:如果在循环的某一次迭代开始之前它是正确的,那么,在下一次迭代开始之前,它也应该保持正确。3.终止:循环能够终止,并且可以得到期望的结果。int BinSearch(int array原创 2016-01-04 13:36:57 · 585 阅读 · 0 评论 -
经典洗牌算法(Knuth-Durstenfeld Shuffle)
有衣服54张的扑克牌,那么它有54!种排列算法。代码如下:void shuffle(int *a, int n){ for(int i = 0; i < n; ++i) swap(a[i], a[randint(i,n-1)];}randint函数的实现:int randint(int i, int j){ if(i < j) sw原创 2016-03-08 11:31:53 · 3852 阅读 · 0 评论