update dir

This commit is contained in:
ranwenjie
2021-08-02 13:27:19 +08:00
parent 3315c86c10
commit 936d401a85
7 changed files with 140 additions and 145 deletions
+34 -37
View File
@@ -10,7 +10,7 @@
* 子串
#### 翻转句子中单词的顺序
## 翻转句子中单词的顺序
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
例如输入“I am a student.”,则输出“student. a am I”。
@@ -79,7 +79,7 @@ char *revert_by_word(char *source){
用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。
#### 左旋转字符串
## 左旋转字符串
>字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
@@ -93,7 +93,7 @@ char *left_rotate(char *str,int offset){
我们可以abcdef分成两部分,ab和cdef,内部逆序以后,整体再次逆序,就可以得到想要的结果了,也就是跟上面的问题是同样的问题。
#### 判断字符串是否是回文
## 判断字符串是否是回文
分析: 2个指针,一头一尾,逐个比较,都相同就是回文
@@ -124,7 +124,7 @@ int is_huiwen(const char *source){
```
#### 只出现一次的字符
## 找到第一个只出现一次的字符
在一个字符串中找到第一个只出现一次的字符。如输入ahbaccdeff,则输出h。
@@ -163,7 +163,7 @@ char char_first_appear_once(const unsigned char *source){
题目扩展:这里的字符换成整数,整数数量几十TB,海量数据处理,显然hash方法不可能,没有那么大得内容
#### 统计文章里单词出现的次数
## 统计文章里单词出现的次数
设计相应的数据结构和算法,尽量高效的统计一片英文文章(总单词数目)里出现的所有英文单词,按照在文章中首次出现的顺序打印输出该单词和它的出现次数。
@@ -178,7 +178,7 @@ void statistics(FILE *fd)
如果是海量数据里面统计top-k次数的单词呢?
#### 替换空格
## 替换空格
实现一个函数,把每个空格替换成 "%20",如输入“we are happy”,则输出“we%20are%20happy”
@@ -220,7 +220,7 @@ char *replace_blank(char *source){
```
#### 小写字母排在大写字母的前面
## 小写字母排在大写字母的前面
有一个由大小写组成的字符串,现在需要对他进行修改,将其中的所有小写字母排在大写字母的前面(大写或小写字母之间不要求保持原来次序),如有可能尽量选择时间和空间效率高的算法 c语言函数原型:
@@ -266,21 +266,21 @@ char *proc(char *str){
}
```
#### 实现字符串转整型的函数
## 实现字符串转整型的函数
也就是实现函数atoi的功能,这道题目考查的就是对各种情况下异常处理。比如:
以"213"分析转换成证书的过程。3+1x10+2x100,思路是:每扫描到一个字符,把之前得到的数字*10,再加上当前的数字
0开头,"0213"
正/负数,"-432" ,"--422","++23"
浮点数,"43.2344"
非法,"2123des"
存在空格," -32"," +432"," 234","23 432","353 "," + 321"
NULL/空串,这时候返回值0
溢出,"32111111112222222222222222222222222222222" , 与 `INT_MAX `比较
* 0开头,"0213"
* 正/负数,"-432" ,"--422","++23"
* 浮点数,"43.2344"
* 非法,"2123des"
* 存在空格," -32"," +432"," 234","23 432","353 "," + 321"
* NULL/空串,这时候返回值0
* 溢出,"32111111112222222222222222222222222222222" , 与 `INT_MAX `比较
* 如何区分正常的'0'和异常情况下返回的结果"0"? 可以通过一个全局变量 g_status 来标示,值为 kValid/kInvalid。
如何区分正常的'0'和异常情况下返回的结果"0"? 可以通过一个全局变量 g_status 来标示,值为 kValid/kInvalid。
```
@@ -292,7 +292,7 @@ int atoi(const char *str){
详细过程也可以[参考这里](http://blog.csdn.net/v_july_v/article/details/9024123)
#### 删除串中指定的字符
## 删除串中指定的字符
删除指定的字符以后,后面的字符都要向前移动一位。这种复杂度是O(N^2);那么有没有O(N)的方法呢?
@@ -318,7 +318,7 @@ char *delete_occurence_character(char *src , char target){
```
#### 在字符串中删除特定的字符
## 在字符串中删除特定的字符
题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”。
@@ -333,7 +333,7 @@ char *delete_occurence_characterset(char *source,const char *del);
#### 删除字符串中的数字并压缩字符串
## 删除字符串中的数字并压缩字符串
如字符串”abc123de4fg56”处理后变为”abcdefg”。注意空间和效率。(下面的算法只需要一次遍历,不需要开辟新空间,时间复杂度为O(N))
这道题跟上一道题也是一个意思。
@@ -360,7 +360,7 @@ char *trim_number(char *source){
#### 字符串原地压缩
## 字符串原地压缩
题目描述:“abeeeeegaaaffa" 压缩为 "abe5ag3f2a",请编程实现。
@@ -384,7 +384,7 @@ char *compress(const char *src,char *dest){
#### 字符串中找出连续最长的数字串
## 字符串中找出连续最长的数字串
写一个函数,功能:
@@ -451,13 +451,13 @@ int longest_continuious_number(const char *input,char *output){
#### 求最大连续递增数字串
## 求最大连续递增数字串
如“ads3sl456789DF3456ld345AA”中的“456789”就是所求。这道题在上一道题目的基础上增加了数字要递增的条件。思路跟上面差不多,碰到不递增的数字就相当于第二个数字串了。
#### 最长公共子串问题
## 最长公共子串问题
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。
@@ -481,7 +481,7 @@ int longest_common_subsequence(const char *s1,const char *s2, char *common){
#### 对称子字符串的最大长度
## 对称子字符串的最大长度
题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
@@ -491,13 +491,10 @@ int longest_common_subsequence(const char *s1,const char *s2, char *common){
int max_symmetrical_char_length(const char *scr);
```
思路一:蛮力法,3重循环(类似 求子数组的最大和 fmax(i,j)问题), fmax(i,j)区间i,j是最长的对称字符
思路二:遍历所有子串,然后判读是否对称 O(n^2)
思路三:有个O(n)复杂度的算法 http://www.cnblogs.com/McQueen1987/p/3559497.html 分析过程如下:
* 思路一:蛮力法,3重循环(类似 求子数组的最大和 fmax(i,j)问题), fmax(i,j)区间i,j是最长的对称字符
* 思路二:遍历所有子串,然后判读是否对称 O(n^2)
* 思路三:有个O(n)复杂度的算法 http://www.cnblogs.com/McQueen1987/p/3559497.html 分析过程如下:
1.
2.
3.
```
int max_symmetrical_char_length(const char *scr){
@@ -507,7 +504,7 @@ int max_symmetrical_char_length(const char *scr){
#### 子串匹配的个数
## 子串匹配的个数
已知一个字符串,比如asderwsde,寻找其中的一个子字符串比如sde的个数,如果没有返回0,有的话返回子字符串的个数。
@@ -517,7 +514,7 @@ char *substr_count(const char *src, const char *substr, int *count)
#### 请编写能直接实现strstr()函数功能的代码。
## 请编写能直接实现strstr()函数功能的代码。
> strstr(str1,str2) 判断str2是否是str1的子串。
@@ -531,7 +528,7 @@ char *strstr(const char *source, const char *target){
```
#### 匹配兄弟字符串
## 匹配兄弟字符串
如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。
@@ -556,7 +553,7 @@ int isBrother(const char *first,const char *secd){
#### 字符串的排列
## 字符串的排列
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。输入字符串 abcca,则输出由 a,b,c排列出来的所有字符串,字符出现个数不变
@@ -569,21 +566,21 @@ int isBrother(const char *first,const char *secd){
#### n个字符串联接
## n个字符串联接
有n个长为m+1的字符串,如果某个字符串的最后m个字符与某个字符串的前m个字符匹配,则两个字符串可以联接,问这n个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。
#### 字符串的集合合并
## 字符串的集合合并
给定一个字符串的集合,格式如:{aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh}要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应输出{aaa bbb ccc ddd hhh},{eee fff}, {ggg}。
#### 编写strcpy 函数
## 编写strcpy 函数
已知strcpy 函数的原型是:
```
+4 -4
View File
@@ -46,7 +46,7 @@ void dequeue(Queue);
这里的题目是有关栈和队列的问题。
#### 循环队列中元素个数
## 循环队列中元素个数
如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列头到队列尾的元素个数(包含队列头、队列尾)
@@ -67,7 +67,7 @@ else
#### 设计包含min函数的栈
## 设计包含min函数的栈
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
要求函数min、push以及pop的时间复杂度都是O(1)。
@@ -86,7 +86,7 @@ a < f(top),把 a push 到 辅助栈中
#### 栈的push、pop序列
## 栈的push、pop序列
题目:输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序。为了简单起见,我们假设push序列的任意两个整数都是不相等的。
@@ -114,7 +114,7 @@ a < f(top),把 a push 到 辅助栈中
#### 颠倒栈
## 颠倒栈
题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。
+26 -26
View File
@@ -6,7 +6,7 @@
* 大数问题
#### 求1+2+…+n
## 求1+2+…+n
要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
@@ -23,7 +23,7 @@ int factorial(n){
```
#### 整数的二进制表示中1的个数
## 整数的二进制表示中1的个数
题目:输入一个整数,求该整数的二进制表达中有多少个1。例如输入10,由于其二进制表示为1010,有两个1,因此输出2。
@@ -48,7 +48,7 @@ int one_appear_count_by_binary(int num){
```
#### 请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句
## 请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句
分析:
```
@@ -63,7 +63,7 @@ int one_appear_count_by_binary(int num){
```
#### 把十进制数(long型)分别以二进制和十六进制形式输出,不能使用printf系列
## 把十进制数(long型)分别以二进制和十六进制形式输出,不能使用printf系列
分析:
```
@@ -78,7 +78,7 @@ tmp[i] = tmp[i]>=0 ? tmp[i] : tmp[i]+16;
#### 判断一个自然数是否是某个数的平方
## 判断一个自然数是否是某个数的平方
说明:当然不能使用开方运算。
@@ -103,7 +103,7 @@ int is_powered(int num)
```
#### 1024! 末尾有多少个0?
## 1024! 末尾有多少个0?
分析:
末尾0的个数取决于2和5的个数
@@ -111,7 +111,7 @@ int is_powered(int num)
#### 编程实现两个正整数的除法(和取模)
## 编程实现两个正整数的除法(和取模)
编程实现两个正整数的除法,当然不能用除法操作符。
```
@@ -125,14 +125,13 @@ int div(const int x, const int y)
#### 求两个或N个数的最大公约数和最小公倍数。
## 求两个或N个数的最大公约数和最小公倍数。
## 大整数乘法(或 大整数阶乘)
#### 大整数乘法(或 大整数阶乘)
请使用代码计算1234567891011121314151617181920*2019181716151413121110987654321 。
请使用代码计算`1234567891011121314151617181920*2019181716151413121110987654321` 。
1. 注意结果可能超出长整形的最大范围 2^64-1
2. 采用分治算法,将大整数相乘转换为小整数计算
@@ -141,11 +140,11 @@ int div(const int x, const int y)
#### 两个数相乘,小数点后位数没有限制,请写一个高精度算法
## 两个数相乘,小数点后位数没有限制,请写一个高精度算法
#### 数值的整数次方
## 数值的整数次方
题目:实现函数`double Power(double base, int exponent)`,求base的exponent次方。
@@ -166,7 +165,7 @@ double Power(double base, int exponent)
上面的代码没有考虑: exponent<=0
判断一个浮点数是不是等于0时,不是直接写 base == 0 ,而应该判断它们的差的绝对值是不是小于一个很小的范围
如果指数大于0,我们还可以使用递归实现:a^n = a^(n/2)*a^(n/2) (n为偶数), 通过这个思路也可以实现
如果指数大于0,我们还可以使用递归实现:`a^n = a^(n/2)*a^(n/2)` (n为偶数), 通过这个思路也可以实现
```
2^16 = 2^8 * 2^8
2^8 = 2^4 * 2^4
@@ -176,6 +175,7 @@ double Power(double base, int exponent)
```
用例:
```
2 3 = 8
0 3 = 0
@@ -201,7 +201,7 @@ double Power(double base, unsigned int exponent)
```
#### 求根号2的值
## 求根号2的值
并且按照我的需要列出指定小数位,比如根号2是1.141 我要列出1位小数就是1.1 2位就是1.14, 1000位就是1.141...... 等。。
@@ -211,7 +211,7 @@ double Power(double base, unsigned int exponent)
#### 整数的素数和分解问题
## 整数的素数和分解问题
歌德巴赫猜想说任何一个不小于6的偶数都可以分解为两个奇素数之和。
对此问题扩展,如果一个整数能够表示成两个或多个素数之和,则得到一个素数和分解式。
@@ -229,7 +229,7 @@ double Power(double base, unsigned int exponent)
```
#### 大于K的最小正整数
## 大于K的最小正整数
给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含),指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
@@ -237,16 +237,16 @@ double Power(double base, unsigned int exponent)
#### 给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。
## 给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。
#### 设计一个随机算法
## 设计一个随机算法
给你5个球,每个球被抽到的可能性为30、50、20、40、10,设计一个随机算法,该算法的输出结果为本次执行的结果。输出A,B,C,D,E即可。
#### 构造一个随机发生器
## 构造一个随机发生器
已知一随机发生器,产生0的概率是p,产生1的概率是1-p,现在要你构造一个发生器,
使得它构造0和1的概率均为1/2;构造一个发生器,使得它构造1、2、3的概率均为1/3;...,
@@ -255,14 +255,14 @@ double Power(double base, unsigned int exponent)
#### 两个圆相交
## 两个圆相交
两个圆相交,交点是A1,A2。现在过A1点做一直线与两个圆分别相交另外一点B1,B2。B1B2可以绕着A1点旋转。问在什么情况下,B1B2最长
#### 输入四个点的坐标,求证四个点是不是一个矩形
## 输入四个点的坐标,求证四个点是不是一个矩形
关键点:
1.相邻两边斜率之积等于-1,
@@ -272,15 +272,15 @@ double Power(double base, unsigned int exponent)
#### 排列组合问题
## 排列组合问题
##### 1,2,3,4,5 五个不同的数字,打印不同的排列。这就是一个无向图的遍历,把每个数字看成一个节点。
## 1,2,3,4,5 五个不同的数字,打印不同的排列。这就是一个无向图的遍历,把每个数字看成一个节点。
##### 用1、2、2、3、4、5这六个数字,写一个main函数,打印出所有不同的排列,
## 用1、2、2、3、4、5这六个数字,写一个main函数,打印出所有不同的排列,
如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连.
如:512234、412345 等,要求:"4"不能在第三位,"3"与"5"不能相连.
这是对上一题增加难度。但是需要
1. 去掉 3,5之间的联通
@@ -9,7 +9,7 @@
解决这一类问题时,可以从以下几个方面考虑:
* 万能的蛮力琼剧
* 万能的蛮力穷举
* 散列表空间换事件
* 分治法,然后归并 (归并排序)
* 选择合适的数据结构可以显著提高算法效率 (堆排序求top-k)
@@ -17,7 +17,7 @@
* 贪心算法或动态规划
#### 数组中超过出现次数超过一半的数字
## 数组中超过出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
@@ -25,7 +25,7 @@
#### 找数组里面重复的一个数
## 找数组里面重复的一个数
找数组里面重复的一个数,一个含n个元素的整数数组至少存在一个重复数,请编程实现,在O(n)时间内找出其中任意一个重复数。
@@ -37,7 +37,7 @@
类似问题:找出数组中唯一的重复元素
#### 数组中找出某数字出现的次数
## 数组中找出某数字出现的次数
在排序数组中,找出给定数字的出现次数。比如 [1, 2, 2, 2, 3] 中2的出现次数是3次。
@@ -52,7 +52,7 @@ int binary_search_lash(int *a,int length,int key);
#### 查找最小的k个元素(top-k)
## 查找最小的k个元素(top-k)
题目:输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。
@@ -67,7 +67,7 @@ topMaxK(int *a,int length, int k);
2. 部分排序 维护一个大小为K的数组,由大到小排序,然后遍历所有数据,每个数据跟数组中最小元素比较,如果比最小元素大,就要插入数组了,这里还有寻找插入位置,移动数组元素的cpu消耗。复杂度是N*K
3. 堆排序 。在这的K较大时(比如这道题目:2亿个整数中求最大的100万之和),上面的算法还是有很多可以改进的地方,如采用二分查找定位插入位置,移动数组元素的计算是躲不过去了。那有没有什么数据结构即能`快速查找,还能快速移动元素`呢?最好是O(1)复杂度。
答案就是`二叉堆`。我们可以遍历总量中的每个元素来跟二叉堆中的堆顶元素比较(堆顶元素在`小根堆`中最小值,在`大根堆`中是最大值),这样在0(1)复杂度就可以完成查找操作,揭下来需要的操作就是重新调整推结构,复杂度是O(logk),因此整个操作复杂度是 O(n*logk)
答案就是`二叉堆`。我们可以遍历总量中的每个元素来跟二叉堆中的堆顶元素比较(堆顶元素在`小根堆`中最小值,在`大根堆`中是最大值),这样在0(1)复杂度就可以完成查找操作,揭下来需要的操作就是重新调整推结构,复杂度是O(logk),因此整个操作复杂度是 `O(n*logk)`
`top-k 小的时候用 *大根堆* ,top-k 大得时候用 *小根堆*`
@@ -76,7 +76,7 @@ topMaxK(int *a,int length, int k);
#### 最长公共子序列 (动态规划的经典题目)
## 最长公共子序列 (动态规划的经典题目)
【最大/小差问题】
求相邻元素的最大差值,有无序的实数列V[N],要求求里面大小相邻的实数的差的最大值,关键是要求线性空间和线性时间
@@ -91,24 +91,26 @@ topMaxK(int *a,int length, int k);
#### 找出和为m的2个数
## 找出和为m的2个数
输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组【1、2、4、7、11、15=和数字15。由于4+11=15,因此输出4和11。
```
//返回0找到,返回-1没找到
int findaddends(int *data,int length,int sum,int *a,int *b);
```
分析:
数组升序排列,查找可用二分查找,时间复杂度O(logn),这样问题就变成了找其中一个加数的问题,复杂度为N*logN
数组升序排列,查找可用二分查找,时间复杂度`O(logn)`,这样问题就变成了找其中一个加数的问题,复杂度为`N*logN`
巧妙解法:数组2端向中间扫描,复杂度O(N)
#### 和为m的组合
## 和为m的组合
编程求解:输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来.
@@ -120,21 +122,18 @@ print_sum_detials(int n , int sum)
`动态规划`(类似背包问题)
1. 划分问题
2. 选择状态
3. 状态转移方程
4. 规划方程
#### 若干个数的和与M最为接近
## 若干个数的和与M最为接近
给定一个实数数组,按序排列(从小到大),从数组从找出若干个数,使得这若干个数的和与M最为接近,描述一个算法,并给出算法的复杂度。
#### 递减数列左移后的数组中找数
## 递减数列左移后的数组中找数
一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5}
是由{6,5,4,3,2,1}左移两位形成的,在这种数组中查找某一个数。
@@ -145,7 +144,7 @@ print_sum_detials(int n , int sum)
#### 求子数组的最大和(最大字段和)
## 求子数组的最大和(最大字段和)
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
@@ -185,20 +184,18 @@ print_sum_detials(int n , int sum)
#### 给出一个洗牌算法
## 给出一个洗牌算法
给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里
分析:扑克牌54张【2~10,J,Q,K,A,小王,大王】
分析:扑克牌54张`2~10,J,Q,K,A,小王,大王`
1)产生随机数, 随机数 rand()%54 ,rand()每次运行都一样,要改为srand(time(NULL))
2) 遍历数组, 随机数k属于区间[i,n],然后a[i] 和 随机数 a[k] 对换
#### 重合区间最长的两个区间段
## 重合区间最长的两个区间段
在一维坐标轴上有n个区间段,求重合区间最长的两个区间段
如【-7,21】,【4,23】,【14,100】,【54,76】
@@ -208,7 +205,7 @@ print_sum_detials(int n , int sum)
#### 奇偶分离
## 奇偶分离
给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。
要求:空间复杂度O(1),时间复杂度为O(n)
@@ -220,21 +217,19 @@ print_sum_detials(int n , int sum)
1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次.
每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,
能否设计一个算法实现?
分析:难点在于 `不用辅助空间`。
思路一: sum(数组元素的总和)-sum(1~1000) 得到的差即为重复元素,N较大时注意总和溢出
思路一: `sum(数组元素的总和)-sum(1~1000)` 得到的差即为重复元素,N较大时注意总和溢出
思路二: 异或操作(位运算)
#### 找出数组中两个只出现一次的数字
## 找出数组中两个只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。
请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
@@ -247,7 +242,7 @@ print_sum_detials(int n , int sum)
#### 用递归的方法判断整数组a[N]是不是升序排列
## 用递归的方法判断整数组a[N]是不是升序排列
递归 isAscend(n-1) && a[N-1]< a[N]
@@ -283,7 +278,7 @@ print_sum_detials(int n , int sum)
#### 扑克牌的顺子
## 扑克牌的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。
2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。
@@ -300,7 +295,7 @@ isShunZi(int *a,int length)
#### n个骰子的点数
## n个骰子的点数
把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。
输入n,打印出S的所有可能的值出现的概率。
@@ -311,7 +306,7 @@ isShunZi(int *a,int length)
#### 把数组排成最小的数
## 把数组排成最小的数
题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。
例如输入数组{32, 321},则输出这两个能排成的最小数字32132。
@@ -320,7 +315,7 @@ isShunZi(int *a,int length)
#### 旋转数组中的最小元素。
## 旋转数组中的最小元素。
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。
@@ -333,7 +328,7 @@ isShunZi(int *a,int length)
#### 分割数组
## 分割数组
一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。
能否只用一个额外数组和少量其它空间实现。
@@ -342,14 +337,14 @@ isShunZi(int *a,int length)
#### 约瑟夫环问题
## 约瑟夫环问题
n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,
每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。
当一个数字删除后,从被删除数字的下一个继续删除第m个数字。
求出在这个圆圈中剩下的最后一个数字。
如 0,1,2,3,4,5 删除第2个数字 (n=6,m=2)
如 `0,1,2,3,4,5` 删除第2个数字 (n=6,m=2)
第一次删除:1
第二次删除: 3
第三次删除:5
@@ -361,7 +356,7 @@ n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,
#### 圆形和正方形是否相交
## 圆形和正方形是否相交
用最简单, 最快速的方法计算出下面这个圆形是否和正方形相交
3D坐标系 原点(0.0,0.0,0.0)
@@ -382,7 +377,7 @@ n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,
#### 两个序列和只差最小
## 两个序列和只差最小
有两个序列a,b,大小都为n,序列元素的值任意整数,无序;
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
@@ -394,7 +389,7 @@ var b=[1, 2, 3, 4,5,40];
#### 重新排列使负数排在正数前面
## 重新排列使负数排在正数前面
一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的正负数之间相对顺序
@@ -426,7 +421,7 @@ updated:设置一个起始点j, 一个翻转点k,一个终止点L
#### 求最大重叠区间大小
## 求最大重叠区间大小
题目描述:请编写程序,找出下面“输入数据及格式”中所描述的输入数据文件中最大重叠区间的大小。
对一个正整数 n ,如果n在数据文件中某行的两个正整数(假设为A和B)之间,即A<=n<=B或A>=n>=B ,则 n 属于该行;
@@ -437,14 +432,14 @@ updated:设置一个起始点j, 一个翻转点k,一个终止点L
#### 四对括号可以有多少种匹配排列方式
## 四对括号可以有多少种匹配排列方式
比如两对括号可以有两种:()()和(())
#### 输出1到最大的N位数
## 输出1到最大的N位数
题目:输入数字n,按顺序输出从1最大的n位10进制数。比如输入3,则输出1、2、3一直到最大的3位数即999。
@@ -457,7 +452,7 @@ updated:设置一个起始点j, 一个翻转点k,一个终止点L
#### 和为n连续正数序列
## 和为n连续正数序列
题目:输入一个正数n,输出所有和为n连续正数序列。
@@ -471,20 +466,20 @@ print_continuous_sequence_sum(int n)
思路二: a[small,big] sum[small,big]>N small往前移动,否则,big往前移动。 O(N)复杂度搞定
### 找出和为N+1的2个数
## 找出和为N+1的2个数
一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。
设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1。
复杂度最好是O(n),如果是O(n2)则不得分。
设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于`N+1`。
复杂度最好是`O(n)`,如果是 `O(n2)`则不得分。
分析:列出所有的数对,如输入15,输出【1,14】【2,13】【3,12】。。。
分析:列出所有的数对,如输入15,输出`【1,14】【2,13】【3,12】。。。`
```
int print_sequence_sum(int n)
```
#### 寻找丑数
## 寻找丑数
题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。
@@ -509,7 +504,7 @@ int print_sequence_sum(int n)
#### 调整数组顺序使奇数位于偶数前面
## 调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,
所有偶数位于数组的后半部分。要求时间复杂度为O(n)。
@@ -521,7 +516,7 @@ void reorder(int *data, int length);
```
#### 在从1到n的正数中1出现的次数
## 在从1到n的正数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
@@ -536,22 +531,22 @@ int one_appear_count(int n);
#### 求一个数组的最长递减子序列
## 求一个数组的最长递减子序列
比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}
比如`{9,4,3,2,5,4,3,2}`的最长递减子序列为`{9,5,4,3,2}`
`动态规划`
#### 如何求2个集合的交集
## 如何求2个集合的交集
1.每个集合里面是否有重复元素?
思路一:hash,复杂度O(M+N)
#### 两两之差绝对值最小的值
## 两两之差绝对值最小的值
有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。
如 [-1, 3, 5, 9] 绝对值最小的是2(5-3)
@@ -563,7 +558,7 @@ int one_appear_count(int n);
#### 数值是否连续相邻
## 数值是否连续相邻
一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
注意:
@@ -577,7 +572,7 @@ int one_appear_count(int n);
#### 最长递增子序列
## 最长递增子序列
题目描述:设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列
Lin=< aK1,ak2,…,akm >,其中k1< k2<…< km且aK1< ak2<…< akm。
@@ -590,7 +585,7 @@ Lin=< aK1,ak2,…,akm >,其中k1< k2<…< km且aK1< ak2<…< akm。
#### Fibonacci数列
## Fibonacci数列
题目:定义Fibonacci数列如下:
/ 0 n=0
@@ -609,7 +604,7 @@ f(n)= 1 n=1
#### 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
## 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
{3,6}{2,4,3} m=2
+6 -5
View File
@@ -3,7 +3,7 @@
矩阵在计算机中表示就是二维数组。这部分内容都是有关二维数组和矩阵相关的题目。
#### 二维数组中的查找
## 二维数组中的查找
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
@@ -11,7 +11,7 @@
int exist_inmatrix(int *matrix,int rows,int cols,int num);
```
#### 矩阵中最大的二维矩阵
## 矩阵中最大的二维矩阵
求一个矩阵中最大的二维矩阵(元素和最大).如:
```
@@ -32,7 +32,7 @@ int max_sum_submatrix(int *matrix,int rows,int cols,int *tmatrix,int *trows,int
```
#### 顺时针打印矩阵
## 顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
例如:如果输入如下矩阵:
@@ -100,7 +100,7 @@ void print_matrix_incircle(int *matrix,int rows,int cols,int start){
#### 从小到大输出矩阵的值
## 从小到大输出矩阵的值
思路1:采用归并进行排序然后进行顺序打印
@@ -125,6 +125,7 @@ void printArry(int *a,int rows,int columns)
int* pArr1=new int[rows];//共存有这么多行指针
for(int i=0;i<rows;i++)
pArr1[i]=i*(columns+1);
while(1)
{
int min=arr[pArr1[0]];
@@ -150,7 +151,7 @@ void printArry(int *a,int rows,int columns)
#### n支队伍比赛的名次
## n支队伍比赛的名次
n支队伍比赛,分别编号为0,1,2。。。。n-1,已知它们之间的实力对比关系,存储在一个二维数组w[n][n]中,w[i][j] 的值代表编号为i,j的队伍中更强的一支。
+11 -13
View File
@@ -6,7 +6,7 @@
* 子树
#### 把二元查找树转变成排序的双向链表
## 把二元查找树转变成排序的双向链表
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求`不能创建任何新的结点`,只调整指针的指向。
@@ -35,7 +35,7 @@
#### 在二元树中找出和为某一值的所有路径
## 在二元树中找出和为某一值的所有路径
题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
@@ -64,8 +64,7 @@ struct BinaryTreeNode // a node in the binary tree
2. 不为叶节点,左子树入栈
#### 判断整数序列是不是二元查找树的后序遍历结果
## 判断整数序列是不是二元查找树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回true,否则返回false。
@@ -82,13 +81,12 @@ struct BinaryTreeNode // a node in the binary tree
#### 一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。
## 一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。
复杂度如果是O(n2)则不得分。
#### 二叉树翻转
## 二叉树翻转
输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。例
@@ -120,7 +118,7 @@ struct BSTreeNode // a node in the binary search tree (BST)
```
#### 按层打印二叉树
## 按层打印二叉树
输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。
例如输入
@@ -138,7 +136,7 @@ struct BSTreeNode // a node in the binary search tree (BST)
#### 二元树的深度
## 二元树的深度
题目:输入一棵二元树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
例如:输入二元树:
@@ -167,7 +165,7 @@ struct SBinaryTreeNode // a node of the binary tree
#### 把一个有序整数数组放到二叉树中?
## 把一个有序整数数组放到二叉树中?
分析:本题考察二叉搜索树的建树方法,简单的递归结构。
@@ -178,7 +176,7 @@ struct SBinaryTreeNode // a node of the binary tree
#### 二叉树两个结点的最低共同父结点
## 二叉树两个结点的最低共同父结点
设计一个算法,找出二叉树上任意两个结点的最近共同父结点。复杂度如果是O(n2)则不得分
@@ -200,12 +198,12 @@ struct TreeNode
#### 俩种方法实现二叉树的前序遍历。
## 俩种方法实现二叉树的前序遍历。
递归和非递归
#### 恢复树结构
## 恢复树结构
有一棵树(树上结点为字符串或者整数),请写代码将树的结构和数据写到一个文件中,并能通过读取该文件恢复树结构。
@@ -200,10 +200,15 @@ A说不知道,B说不知道,C说不知道,然后A说知道了。
得:a=(1024/3125)X;
要使a为整数,X最小取3125.
减去加上的4个,所以,这堆桃子最少有3121个。
已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。
(参考答案:这题主要考的是对概率的理解。程序关键是要算出rand10,1到10,十个数字出现的考虑都为10%.根据排列组合,连续算两次rand7出现的组合数是7*7=49,这49种组合每一种出现考虑是相同的。怎么从49平均概率的转换为1到10呢?方法是:
1.rand7执行两次,出来的数为a1=rand7()-1,a2=rand7()-1.
2.如果a1*7+a2<40,b=(a1*7+a2)/4+1;如果a1*7+a2>=40,重复第一步。参考代码如下所示:
2.如果`a1*7+a2<40,b=(a1*7+a2)/4+1`;如果`a1*7+a2>=40`, 重复第一步。参考代码如下所示:
```
int rand7()
{
return rand()%7+1;
@@ -220,8 +225,7 @@ int rand10()
} while (a10>= 40);
return (a71*7+a72)/4+1;
}
```