From 936d401a85ad759fce43dcb13f0386fe115dccc2 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Mon, 2 Aug 2021 13:27:19 +0800 Subject: [PATCH] update dir --- 9 Algorithms Job Interview/1 字符串.md | 71 ++++++------ 9 Algorithms Job Interview/3 堆和栈.md | 8 +- 9 Algorithms Job Interview/4 数值问题.md | 52 ++++----- 9 Algorithms Job Interview/5 数组数列问题.md | 109 +++++++++---------- 9 Algorithms Job Interview/6 矩阵.md | 11 +- 9 Algorithms Job Interview/7 二叉树.md | 24 ++-- 9 Algorithms Job Interview/9 智力思维训练.md | 10 +- 7 files changed, 140 insertions(+), 145 deletions(-) diff --git a/9 Algorithms Job Interview/1 字符串.md b/9 Algorithms Job Interview/1 字符串.md index fedd6ba..a038344 100644 --- a/9 Algorithms Job Interview/1 字符串.md +++ b/9 Algorithms Job Interview/1 字符串.md @@ -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 函数的原型是: ``` diff --git a/9 Algorithms Job Interview/3 堆和栈.md b/9 Algorithms Job Interview/3 堆和栈.md index 5546d04..b26f180 100644 --- a/9 Algorithms Job Interview/3 堆和栈.md +++ b/9 Algorithms Job Interview/3 堆和栈.md @@ -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处在栈顶。 diff --git a/9 Algorithms Job Interview/4 数值问题.md b/9 Algorithms Job Interview/4 数值问题.md index 74bc07f..8544f52 100644 --- a/9 Algorithms Job Interview/4 数值问题.md +++ b/9 Algorithms Job Interview/4 数值问题.md @@ -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之间的联通 diff --git a/9 Algorithms Job Interview/5 数组数列问题.md b/9 Algorithms Job Interview/5 数组数列问题.md index c5e3f6b..5c4d002 100644 --- a/9 Algorithms Job Interview/5 数组数列问题.md +++ b/9 Algorithms Job Interview/5 数组数列问题.md @@ -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=是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 diff --git a/9 Algorithms Job Interview/6 矩阵.md b/9 Algorithms Job Interview/6 矩阵.md index c6e264d..826c0a5 100644 --- a/9 Algorithms Job Interview/6 矩阵.md +++ b/9 Algorithms Job Interview/6 矩阵.md @@ -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=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; } - - +```