算法编程
懒先森要努力
最淡的墨水也胜于最强的记忆
展开
-
输入任意数字,用中文输出
实现如下函数:void printInChinese(int num);这个函数输入一个小于100000000(一亿)的正整数,并在屏幕上打印这个数字的中文写法。例如:17 -> 一十七120 -> 一百二十201 -> 二百零一1074 -> 一千零七十四65536 -> 六万五千五百三十六1010101 -> 一百零一万零一百零一提示:请注意‘零’的处理转载 2013-10-04 17:00:34 · 1184 阅读 · 0 评论 -
100盏灯泡的开关问题
问题:有100盏灯泡,第一轮点亮所有电灯,第二轮每两盏灯熄灭一盏,即熄灭第2盏,第4盏,以此类推,第三轮改变编号为3的倍数的电灯,第3盏,第6盏,如果原来那盏灯是亮的,就熄灭它,如果原来是灭的,就点亮它,以此类推,直到第100轮。问第100结束后,还有多少盏灯泡是亮的?解答:由题意最如果最后某一盏灯是亮着的,那么它一定是被切换了奇数次(第0次的时候全部都关着)。首先来看一下转载 2013-10-04 19:41:32 · 584 阅读 · 0 评论 -
把字符串里面连续的数字依次存放到一个数组中
#include#include#includeint main(int argc, char* argv[]){ const char str[256] = "abc123de4f67"; char sNumbers[32][32]; int i = 0,j = 0,k = 0; int len = strlen(str); int bNumber = 0; whi转载 2013-10-04 20:15:48 · 4238 阅读 · 0 评论 -
字符串包含问题的求解
我们在参加笔试或者写代码的时候总会与字符串打交道,今天主要想说的是如何解决字符串包含的问题。问题是,给你一个字符串然后让你循环移位能否得到一个给定的字符串,比如给你ABCDE 能否将其进行移位得到CDEA,这样的问题。遇到这样的 问题我们可能第一件事就是对其进行循环移位,这个方法是没有问题的,但是我们想想如果字符串很长很长,那么我们的效率是不是会很高呢?时间复杂度应该为字符串的长度。这样肯转载 2013-10-04 20:27:04 · 578 阅读 · 0 评论 -
整数数组,长度为n,分为m份。求m最大值
题目:.一个整数数组a,长度为n,将其分为m份,使各份的和相等,求m的最大值 比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1; {3,6}{2,4,3} m=2 {3,3}{2,4}{6} m=3 所以m的最大值为3解答:找了半天没有更好的解法,以下两个思路供参考。 基本思想都是 1求转载 2013-10-05 10:34:08 · 1770 阅读 · 0 评论 -
由1-7的随机整数函数构造1-10随机整数函数
题目:已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。分析:要保证rand10()在整数1-10的均匀分布,可以构造一个1-10*n的均匀分布的随机整数区间(n为任何正整数)。假设x是这个1-10*n区间上的一个随机整数,那么x%10+1就是均匀分布在1-10区间上的整数。由于(rand7()-1)*7转载 2013-10-05 12:32:41 · 857 阅读 · 0 评论 -
兄弟单词 — 两种算法实现
本文实现两种方法的代码,方法如下:方案一:使用数据结构 map。兄弟单词共用一个签名key,key为单词内部排序后的词条,list存储同一key的单词集合;相对于编程珠玑中的方法,该方法在空间上节省了每个单词一个key的空间;在时间上,不再需要二分查找,O(1)的查找;但是这种方法还可以优化,见方案二方案二:使用trie树。trie树又称字典树,在面试题中关于“字符串”与“数字串”转载 2013-10-05 17:02:20 · 647 阅读 · 0 评论 -
从计算杨辉三角(Pascal Triangle)看算法优化
杨辉,字谦光,北宋时期杭州人。在他1261年所著的《详解九章算法》一书中,辑录了三角形数表,称之为“开方作法本源”图。 杨辉三角是一个由数字排列成的三角形数表,一般形式如下: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1杨转载 2013-10-07 08:30:23 · 741 阅读 · 0 评论 -
约瑟夫问题
我们回到解题思路上,考虑一般的情况,n个人排成一圈,从第1个人开始报数,报数口号从1到m(报到m的人从圆圈里出去),循环直到只剩一个人,问最后剩下的人开始的编号是多少?假设答案ans = F(n,m)。则F(1,m)=1; F(2,2) = 1; F(2,3) = 2;假设有n个数: 1,2,3,4,5,6....,n-2,n-1,n。中奖的第一个人的序号一定是:a1 =转载 2013-10-06 09:22:23 · 572 阅读 · 0 评论 -
O(n)回文子串算法
注:转载的这篇文章,我发现下面那个源代码有点bug。。。在下一篇博客中改正了。。 这里,我介绍一下O(n)回文串处理的一种方法。Manacher算法.原文地址:http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-palindro转载 2013-10-07 21:09:11 · 563 阅读 · 0 评论 -
有两个序列A和B,求k个最小的(ai+bj)
题目:有两个序列A和B,A=(a1,a2,...,ak),B=(b1,b2,...,bk),A和B都按升序排列,对于1解法一:看到这个题目,第一个想法就是求出所有组合的加法结果,然后建立一个大小为k的堆,利用这堆来求出最小的k个和值。那么这种方法需要花费O(k^2)来求出所有组合的和值,然后花费O(k^2lgk)时间来找出满足要求的k个和值。所以最终时间复杂度为O(k^2lgk)。空间复杂度为转载 2013-10-10 10:12:26 · 2767 阅读 · 0 评论 -
组合问题(从M个不同字符中任取N个字符的所有组合)
void find(char *source, char *result, int n) { if(n==1) { while(*source) printf("%s%c\n", result, *source++); } else { int i, j; for(i=0; source != 0; i++); for(j=0; result[j] != 0转载 2013-10-21 15:11:30 · 944 阅读 · 0 评论 -
最大连续递增数字串
求最大连续递增数字串(如“ads3sl456789DF3456ld345AA”中的“456789”)int GetSubString(char *strSource, char *strResult) { int iTmp=0, iHead=0, iMax=0; for(int Index=0, iLen=0; strSource[Index]; Index++) { if(转载 2013-11-16 22:14:25 · 1102 阅读 · 0 评论 -
12个高矮不同的人,排成两排——Catalan数
问题描述: 12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? 还有一道和这个题相关的题:http://blog.csdn.net/jiyanfeng1/article/details/8068811 (平衡括号问题)和(异构BST问题)问题分析: 我们先把这12个人从低到高排列,然后,选择6个人排在第一排,那么剩转载 2013-11-19 22:45:39 · 716 阅读 · 0 评论 -
任务分配的最优方案
四个工人,四个任务,每个人做不同的任务需要的时间不同,求任务分配的最优方案。#include "stdafx.h"#define N 4int Cost[N][N] = { {2, 12, 5, 32}, // 行号:任务序号,列号:工人序号{8, 15, 7, 11}, // 每行元素值表示这个任务由不同工人完成所需要的时间{24, 18, 9, 6},{21, 1, 8, 2转载 2013-11-07 19:34:11 · 2275 阅读 · 0 评论 -
猴子吃桃子问题
/** * * 有一只猴子,第一天摘了若干个桃子 , * 当即吃了一半,但还觉得不过瘾 ,就又多吃了一个。 * 第2天早上又将剩下的桃子吃掉一半,还是觉得不过瘾,就又多吃了两个。 * 以后每天早上都吃了前一天剩下的一半加天数个 * (例如,第5天吃了前一天剩下的一般加5个)。 * 到第n天早上再想吃的时候,就只剩下一个桃子了。 * 输入:天数n * 输出:第转载 2013-10-04 18:39:28 · 628 阅读 · 0 评论 -
时分秒针重合
问题在一天的24小时之中,时钟的时针、分针和秒针完全重合在一起的时候有几次?都分别是什么时间?你怎样算出来的?分析初看此问题觉得很简单,但是网上各种版本的答案都各不相同,那到底谁是对的呢?我们可以这样考虑——龟兔赛跑,跑得慢的针终归会被快的一圈一圈超过。那么,分别求出时针分针、分针秒针的重合时间,然后再看是否有相同。这里都不难,关键是有一个陷阱!请问大家,我说“转载 2013-10-05 11:30:28 · 909 阅读 · 0 评论 -
写一个函数,求两个整数的之和,要求在函数体内不得使用+、-、×、÷
分析:这又是一道考察发散思维的很有意思的题目。当我们习以为常的东西被限制使用的时候,如何突破常规去思考,就是解决这个问题的关键所在。看到的这个题目,我的第一反应是傻眼了,四则运算都不能用,那还能用什么啊?可是问题总是要解决的,只能打开思路去思考各种可能性。首先我们可以分析人们是如何做十进制的加法的,比如是如何得出5+17=22这个结果的。实际上,我们可以分成三步的:第一步只做各位相加不进位转载 2013-10-05 11:20:19 · 1035 阅读 · 0 评论 -
提灯过桥问题
题目:小明一家过一座桥,过桥时是黑夜,所以必须有灯。现在小明过桥要1秒,小明的弟弟要3秒,小明的爸爸要6秒,小明的妈妈要8秒,小明的爷爷要12秒。每次此桥最多可过两人,而过桥的速度依过桥最慢者而定,而且灯在点燃后30秒就会熄灭。问:小明一家如何过桥?思路:其实是考察应聘者在限制条件下解决问题的能力。具体到这道题目来说,很多人往往认为应该由小明持灯来来去去,这样最节省时间,但最后却怎么也凑不转载 2013-10-04 20:04:52 · 5550 阅读 · 0 评论 -
旋转字符串的三种算法
题目:给定一个长度为n的字符串,将它向左旋转i个位置,例如,str = "abcdefg", n = 7, i = 3,则旋转后,str = "defgabc",要求空间复杂度为1。一般,解旋转字符串这样的题目,最简单的做法即是先将前i个字符拷贝到临时空间,然后将后n - i个字符前移,最后再将临时空间中的数据拷贝到原字符串的后i个位置上。但这样做会额外浪费i个空间。现给出如下三种算法:转载 2013-10-04 20:46:17 · 719 阅读 · 0 评论 -
如何判断一个整数数组中是否有重复元素
题目:写一个函数判断一个int类型的数组是否是有效的。 所谓有效是指:假设数组大小为n,那么这个int数组里的值为0~n-1之间的数,并且每个数只能出现一次,否则就是无效数组。 例如[5,3,1,4,2,0]是有效的,[5,3,5,1,2,0]是无效的,[5,3,6,1,2,0]是无效的。 解法思路一:置换的思想用一个temp来存储被置换出来的值,例如数组转载 2013-10-05 10:34:55 · 4264 阅读 · 1 评论 -
删除字符串中的数字并压缩字符串
如字符串”abc123de4fg56”处理后变为”abcdefg”。注意空间和效率。(下面的算法只需要一次遍历,不需要开辟新空间,时间复杂度为O(N))。#include "stdafx.h"void delNum(char *str) { int i, j=0; // 找到串中第一个数字的位子 for(i=j=0; str && (str'9'); j=++i) ; /转载 2013-10-05 10:50:40 · 996 阅读 · 0 评论 -
给定无序自然数数组,求最大连续自然数个数,时间复杂度为O(n)
维持两个hash表tables: Start表,其中的条目都是如下格式(start-point,length),包含的某个连续序列起始数以及序列长度。 End表,其中的条目都是如下格式(end-point,length),包含的某个连续序列结束数以及序列长度。 扫描原始数组,做如下操作: 对于当前值value, 判断value + 1是否存在于start表中。 如果存在,转载 2013-10-05 11:24:04 · 1556 阅读 · 0 评论 -
如何计算两个有序整型数组的交集
例如两个含有n个元素的有序(非降序)整型数组a和b(数组a与b中都没有重复元素),求出其共同元素,a = 0, 1, 2, 3, 4b = 1, 3, 5, 7, 9那么它们的交集为{1, 3}。计算数组交集可以采用很多种方法,但数组的相对大小一般会影响算法的效率,所以需要根据两个数组的相对大小来确定采用的方法:(1)对于两个数组长度相当的情况,一般可以采取如下三种方法。方转载 2013-10-04 18:55:38 · 995 阅读 · 0 评论 -
打印前N个素数
题目:打印前N个素数,不需要考虑大数和溢出思路:从2开始,依次检测后续的每个数,若为素数,计数加1,直到计数到N。分析:问题复杂度的瓶颈在于判断一个数是否为素数。鉴于前面的素数已经找出,可以将所有找出的素数保存下来,在判断一个数x是否为素数时,只需判断该数x是否能整除[2,sqrt(x)]内的所有素数即可。/* * 打印前N个素数 * 不需要考虑大数和溢出的情况 * */转载 2013-10-04 19:49:55 · 1226 阅读 · 0 评论 -
大整数相乘
void Multiple(char A[], char B[], char C[]) { int TMP, In=0, LenA=-1, LenB=-1; while(A[++LenA] != '\0'); while(B[++LenB] != '\0'); int Index, Start = LenA + LenB - 1; for(int i=LenB-1; i>=0; i--转载 2013-10-04 20:08:38 · 476 阅读 · 0 评论 -
分解质因数
如:435234=251*17*17*3*2void prim(int m, int n) { if(m>n) { while(m%n != 0) n++; m /= n; prim(m, n); printf("%d*", n); }}int main(int argc, char* argv[]){ int n = 435234; printf("%d=转载 2013-10-05 08:45:56 · 614 阅读 · 0 评论 -
野人过河问题
这是某安全公司的笔试题,它的题目包括几十道选择题,和一道主观题,即野人过河问题。选择题涉及智力题、计算机组成原理、正则、C语言、操作系统等方面,而主观题,则是搜索中的经典题型。野人过河问题题意如下:有M个牧师(也有的翻译为传教士)和C个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险. 你能不能找出一种安全的渡河方法呢(M>=C)转载 2013-10-05 09:05:55 · 1440 阅读 · 0 评论 -
飞机加油飞地球一圈的问题
题目:假设有N架飞机,必须从同1飞机场起飞,不许中途降落,可空中互相加油,每个飞机油箱最多只能飞地球半圈,问至少需要多少飞机才能保证至少1架飞机绕地球1圈。 此题关键一点:地球是圆的。可以往相反的方向飞,这一点也不违背题目中只能从同一个机场起飞的前提。解题思路:1:3架飞机从起点o经右往左飞。此时油量为4、4、4。飞到A点时。油量变成3、转载 2013-10-05 09:23:05 · 1091 阅读 · 0 评论 -
不开辟用于交换数据的临时空间,如何完成字符串的逆序
#include "stdafx.h"void change(char *str) { for(int i=0,j=strlen(str)-1; i<j; i++, j--) { str ^= str[j] ^= str ^= str[j]; }}int main(int argc, char* argv[]) { char str[] = "abcdefg"; print转载 2013-10-05 10:51:51 · 1414 阅读 · 1 评论 -
字符串数组所有排列,找指定串位置
字符串数组seq[] = a,b,c,d,aa,ba,ca,da,ab,bb,cb,db,ac...,aaa,aba,...(1)aaa是第几个字符串(2)ababacd是第几个(3)第1000个字符串是什么(4)编写函数find(),返回字符串在seq中是第几个(语言不限)分析:(1).长度,很容易推导出长度是n的字符串在第4^(n-1)个之后,aaa是1位和2位全排转载 2013-10-05 11:04:59 · 949 阅读 · 0 评论 -
两个有意思的递归小程序
最近听到的两道面试、笔试题,感觉挺有意思的:1。实现库函数strlen,不能使用任何库函数,不能定义任何变量。2。实现函数strrev,该函数有两个参数,将其中一个字符串逆序放到另一个字符串指针中,同样要求不能使用任何库函数,不能定义任何变量。采用递归实现,刚好可以满足这两道题的要求:void strrev(char **dest, const char *src)转载 2013-10-05 11:11:14 · 601 阅读 · 0 评论 -
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻#include #include #include #define STUDENT_NUM 50int student[STUDENT_NUM] = {0};bool IsInSet(int pos, int number){ for (int i = 0; i < pos; i++) {转载 2013-11-08 18:34:56 · 2193 阅读 · 0 评论