① 面试算法知识梳理(14) - 数字算法
面试算法知识梳理(1) - 排序算法
面试算法知识梳理(2) - 字符串算法第一部分
面试算法知识梳理(3) - 字符串算法第二部分
面试算法知识梳理(4) - 数组第一部分
面试算法知识梳理(5) - 数组第二部分
面试算法知识梳理(6) - 数组第三部分
面试算法知识梳理(7) - 数组第四部分
面试算法知识梳理(8) - 二分查找算法及其变型
面试算法知识梳理(9) - 链表算法第一部分
面试算法知识梳理(10) - 二叉查找树
面试算法知识梳理(11) - 二叉树算法第一部分
面试算法知识梳理(12) - 二叉树算法第二部分
面试算法知识梳理(13) - 二叉树算法第三部分
斐波那契数列 满足下面的通项公式,要求给出 N ,输出第 N 项的 F(N)
这里介绍两种解决办法, 循环算法 和 矩阵算法 。循环算法比较容易理解,就是从 F(0) 开始,根据通项公式,得到下一个斐波那契数列中的数字即可。
对于上面的通项公式,可以用下面的矩阵乘法的形式来表示
一个台阶总共有 n 级,如果一次可以跳 1 级,也可以跳 2 级,求总共有多少总跳法。
由于有两种跳台阶方式,因此跳 n 级台阶可以转换为下面两个问题之和:
这就和之前的斐波那契数列的通项公式相同。
这个问题,需要先总结一下规律,我们根据数字 N 的 位数 来进行分析:
那么 N>=1 时才会出现 1 ,并且出现 1 的次数为 1 次
在这种情况下,出现 1 的次数等于个位上出现 1 的次数加上十位上出现 1 的个数。
例如,如果要计算百位上 1 出现的次数,它要受到三方面的影响:百位上的数字,百位以下的数字,百位以上的数字。
对于一个二进制数,例如 1010 ,将其减 1 后得到的结果是 1001 ,也就是将最后一个 1 (倒数第二位)及其之后的 0 变成 1 , 1 变成 0 ,再将该结果与原二进制数相与,也就是 1010 & 1001 = 1000 ,那么就可以去掉最后一个 1 。
因此,如果需要计算两个数的二进制表示中有多少位是不同的,可以 先将这两个数异或 ,那么不相同的位数就会变成 1 ,之后利用上面的技巧,通过每次去掉最后一个 1 ,来 统计该结果中 1 的个数 ,就可以知道两个数的二进制表示中有多少是不同的了。
N! 的含义为 1*2*3*...*(N-1)*N ,计算 N! 的十进制表示中,末尾有多少个 0 。
N! 中能产生末尾是 0 的质数组合是 2*5 ,所以 N! 末尾的 0 的个数取决了 2 的个数和 5 的个数的最小值,有因为被 2 整除的数出现的概率大于 5 ,因此 5 出现的次数就是 N! 末尾 0 的个数。因此,该问题就转换成为计算从 1~N ,每个数可以贡献 5 的个数,也就是每个数除以 5 的值。
上面的解法需要从 1 到 N 遍历每一个数,当然还有更加简便的方法。以 26! 为例,贡献 5 的数有 5、10、15、20、25 ,一共贡献了 6 个 5 ,可以理解为 5 的倍数 5、10、15、20、25 贡献了一个 5 ,而 25 的倍数又贡献了一个 5 ,得到下面的公式:
首先,让我们换一个角度考虑,其实这个问题就是求解二进制表示中从最低位开始 0 的个数,因为二进制最低位为 0 代表的是偶数,能够被 2 整除,所以质因数 2 的个数就是二进制表示中最低位 1 后面的 0 的个数。
因此,我们的实现这就和上面 2.7 中求解质因数 5 的个数是一样的。
最大公约数 的定义为 两个或多个整数的共有约数中最大的一个 。这里采用的是 更相止损法 ,其操作步骤为:
则第一步中约掉的若干个 2 与第二步中等数的乘积就是所求的最大公约数。
有限小数或者无限循环小数都可以转化为分数,例如:
在 http://blog.csdn.net/flyfish1986/article/details/47783545 这边文章中,详细地描述了该题的解决思路,核心思想就是将原小数分为 有限部分 和 无限循环小数 部分,对于这两部分别进行处理。
② 面试会出哪些经典算法题
如下:
1、排序算法∶快速排序、归并排序、计数排序
2、搜索算法∶回溯、递归、剪枝技巧
3、图论∶最短路、最小生成树、网络流建模
4、动态规划:背包问题、最长子序列、计数问题
5、基础技巧:分治、倍增、二分、贪心
6、数组与链表:单/双向链表、跳舞链
7、栈与队列
8、树与图:最近公共祖先、并查集
9、哈希表
10、堆:大/小根堆、可并堆
11、字符串∶字典树、后缀树
算法简介:
算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。
如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
算法中的指令描述的是一个计算,当其运行时能从一个初始状态和(可能为空的)初始输入开始,经过一系列有限而清晰定义的状态,最终产生输出并停止于一个终态。一个状态到另一个状态的转移不一定是确定的。随机化算法在内的一些算法,包含了一些随机输入。
形式化算法的概念部分源自尝试解决希尔伯特提出的判定问题,并在其后尝试定义有效计算性或者有效方法中成形。
这些尝试包括库尔特·哥德尔、Jacques Herbrand和斯蒂芬·科尔·克莱尼分别于1930年、1934年和1935年提出的递归函数,阿隆佐·邱奇于1936年提出的λ演算,1936年Emil Leon Post的Formulation 1和艾伦·图灵1937年提出的图灵机。即使在当前,依然常有直觉想法难以定义为形式化算法的情况。
③ 面试算法题:你的任务就是计算出长度为n的字符串(只包含‘A’、‘B’和‘C’),有多少个是暗黑字符串。
程序肯定不是判断一个字符串是纯洁的还是黑暗的。从现有的题目描述看,程序和题目没有关系。
题目是否不全?
④ 大公司笔试面试有哪些经典算法题目
大公司的笔试面试一般是针对你所面试的岗位进行一些专业知识的考核,不会出现想考公员里面的行测似得,当然也有哪些逆向思维的计算题。
⑤ 面试题 描述java中字符串的比较方式有哪些
java中的字符串比较方法:
1)string1.equals(string2)
2) str1==str2 。
java中字符串的比较是==比较引用,equals 比较值的做法。但是不同的声明方法字符串的比较结果也是不同的。
例如: String str1=new String("a");
String str2=new String("a");
str1==str2 输出false
str1.equals(str2) 输出true
而如果这样声明
String str1="a";
String str2="a";
str1==str2 输出true
str1.equals(str2) 输出true
这是因为 equals 方法本来也是比较引用的字符串类在实现的时候重写了该方法。
第一种声明方法等于是声明了两个对象,用’==‘比较是时候比较的是引用输出的是false 由于他们的值相同用equals的时候就比较的是值了,输出true。
第二种情况不是因为比较有与第一种有差异,而是因为声明有差异,第二种声明方法在声明的时候有堆或堆栈 共用的现象,也就是说
在声明的时候如果如果声明为类属性他会检查在堆栈中有没有与现在声明的是相同结构的字符串。如果有就直接将地址指向已有内存地址。声明在方法内部的局部变
量原理一样只不过他是堆栈共享。
⑥ 大公司笔试面试有哪些经典算法题目
1、二维数组中的查找
具体例题:如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列, {1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。现在给出一个数字序列,允许使用一种转换操作:选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列?
⑦ 测试开发面试必知算法
测试开发的技能之一就是需要掌握一些开发的语言,而针对于考察开发语言,业界内比较容易采用的方式就是考察各种算法。在此做一个简单的总结(最近比较喜欢玩Python,所以都是以Python为例子,其它的语言类推。)
冒泡排序
冒泡排序算法的运作如下:(从后往前)
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
实例:对列表 [2, 8, 4, 7, 5, 9, 0]进行冒泡排序
递归
递归过程一般通过函数或子过程来实现。递归方法:在函数或子过程的内部,直接或者间接地调用自己的算法。
实例:要计算1-10的10位数字的乘积,直观的算法是1 2 3 4 5 6 7 8 9,利用递归则思路是循环执行n*n-1,直到n=1时
二叉树遍历算法
从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
⑴访问结点本身(N),
⑵遍历该结点的左子树(L),
⑶遍历该结点的右子树(R)。
以上三种操作有六种执行次序:
NLR、LNR、LRN、NRL、RNL、RLN。
二叉树的节点表示可以使用
前序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
实例:求二叉树深度和宽度
求深度用递归;求宽度用队列,然后把每层的宽度求出来,找出最大的就是二叉树的宽度
字符串倒序输出
思路一:索引的方法
思路二:借组列表进行翻转
后续还有的话会继续添加的。
⑧ java面试有哪些算法
面试-java算法题:
1.编写一个程序,输入n,求n!(用递归的方式实现)。
public static long fac(int n){ if(n<=0) return 0; else if(n==1) return 1; else return n*fac(n-1);
} public static void main(String [] args) {
System.out.println(fac(6));
}
2.编写一个程序,有1,2,3,4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
public static void main(String [] args) { int i, j, k; int m=0; for(i=1;i<=4;i++) for(j=1;j<=4;j++) for(k=1;k<=4;k++){ if(i!=j&&k!=j&&i!=k){
System.out.println(""+i+j+k);
m++;
}
}
System.out.println("能组成:"+m+"个");
}
3.编写一个程序,将text1.txt文件中的单词与text2.txt文件中的单词交替合并到text3.txt文件中。text1.txt文件中的单词用回车符分隔,text2.txt文件中用回车或空格进行分隔。
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class text{
public static void main(String[] args) throws Exception{
String[] a = getArrayByFile("text1.txt",new char[]{'\n'});
String[] b = getArrayByFile("text2.txt",new char[]{'\n',' '});
FileWriter c = new FileWriter("text3.txt");
int aIndex=0; int bIndex=0;
while(aIndex<a.length){
c.write(a[aIndex++] + "\n");
if(bIndex<b.length)
c.write(b[bIndex++] + "\n");
}
while(bIndex<b.length){
c.write(b[bIndex++] + "\n");
}
c.close();
}
public static String[] getArrayByFile(String filename,char[] seperators) throws Exception{
File f = new File(filename);
FileReader reader = new FileReader(f);
char[] buf = new char[(int)f.length()];
int len = reader.read(buf);
String results = new String(buf,0,len);
String regex = null;
if(seperators.length >1 ){
regex = "" + seperators[0] + "|" + seperators[1];
}else{
regex = "" + seperators[0];
}
return results.split(regex);
}
}
4.639172每个位数上的数字都是不同的,且平方后所得数字的所有位数都不会出现组成它自身的数字。(639172*639172=408540845584),类似于639172这样的6位数还有几个?分别是什么?
这题采用的HashMap结构判断有无重复,也可以采用下题的数组判断。
public void selectNum(){
for(long n = 100000; n <= 999999;n++){
if(isSelfRepeat(n)) //有相同的数字,则跳过
continue;
else if(isPingFangRepeat(n*n,n)){ //该数的平方中是否有与该数相同的数字
continue;
} else{ //符合条件,则打印 System.out.println(n);
}
}
} public boolean isSelfRepeat(long n){
HashMap<Long,String> m=new HashMap<Long,String>(); //存储的时候判断有无重复值
while(n!=0){ if(m.containsKey(n%10)){ return true;
} else{
m.put(n%10,"1");
}
n=n/10;
} return false;
} public boolean isPingFangRepeat(long pingfang,long n){
HashMap<Long,String> m=new HashMap<Long,String>(); while(n!=0){
m.put(n%10,"1");
n=n/10;
} while(pingfang!=0){ if(m.containsKey(pingfang%10)){ return true;
}
pingfang=pingfang/10;
} return false;
} public static void main(String args[]){ new test().selectNum();
}
5.比如,968548+968545=321732732它的答案里没有前面两个数里的数字,有多少这样的6位数。
public void selectNum(){
for(int n = 10; n <= 99;n++){
for(int m = 10; m <= 99;m++){ if(isRepeat(n,m)){ continue;
} else{
System.out.println("组合是"+n+","+m);
}
}
}
} public boolean isRepeat(int n,int m){ int[] a={0,0,0,0,0,0,0,0,0,0}; int s=n+m; while(n!=0){
a[n%10]=1;
n=n/10;
} while(m!=0){
a[m%10]=1;
m=m/10;
} while(s!=0){ if(a[s%10]==1){ return true;
}
s=s/10;
} return false;
} public static void main(String args[]){ new test().selectNum();
}
6.给定String,求此字符串的单词数量。字符串不包括标点,大写字母。例如 String str="hello world hello hi";单词数量为3,分别是:hello world hi。
public static void main(String [] args) { int count = 0;
String str="hello world hello hi";
String newStr="";
HashMap<String,String> m=new HashMap<String,String>();
String [] a=str.split(" "); for (int i=0;i<a.length;i++){ if(!m.containsKey(a[i])){
m.put(a[i],"1");
count++;
newStr=newStr+" "+a[i];
}
}
System.out.println("这段短文单词的个数是:"+count+","+newStr);
}
7.写出程序运行结果。
public class Test1 { private static void test(int[]arr) { for (int i = 0; i < arr.length; i++) { try { if (arr[i] % 2 == 0) { throw new NullPointerException();
} else {
System.out.print(i);
}
} catch (Exception e) {
System.out.print("a ");
} finally {
System.out.print("b ");
}
}
}
public static void main(String[]args) { try {
test(new int[] {0, 1, 2, 3, 4, 5});
} catch (Exception e) {
System.out.print("c ");
}
}
}
运行结果:a b 1b a b 3b a b 5b
public class Test1 { private static void test(int[]arr) { for (int i = 0; i < arr.length; i++) { try { if (arr[i] % 2 == 0) { throw new NullPointerException();
} else {
System.out.print(i);
}
}
finally {
System.out.print("b ");
}
}
}
public static void main(String[]args) { try {
test(new int[] {0, 1, 2, 3, 4, 5});
} catch (Exception e) {
System.out.print("c ");
}
}
}
运行结果:b c
8.单词数
统计一篇文章里不同单词的总数。
Input
有多组数据,每组一行,每组就是一篇小文章。每篇小文章都是由小写字母和空格组成,没有标点符号,遇到#时表示输入结束。
Output
每组值输出一个整数,其单独成行,该整数代表一篇文章里不同单词的总数。
Sample Input
you are my friend
#
Sample Output
4
public static void main(String [] args) {
List<Integer> countList=new ArrayList<Integer>(); int count;
HashMap<String,String> m;
String str; //读取键盘输入的一行(以回车换行为结束输入) String[] a;
Scanner in=new Scanner(System.in);
while( !(str=in.nextLine()).equals("#") ){
a=str.split(" ");
m=new HashMap<String,String>();
count = 0; for (int i=0;i<a.length;i++){ if(!m.containsKey(a[i]) && (!a[i].equals(""))){
m.put(a[i],"1");
count++;
}
}
countList.add(count);
}s for(int c:countList)
System.out.println(c);
}
⑨ 面试难点!常用算法技巧之“滑动窗口”
滑动窗口,顾名思义,就是有一个大小可变的窗口,左右两端方向一致的向前滑动(右端固定,左端滑动;左端固定,右端滑动)。
可以想象成队列,一端在push元素,另一端在pop元素,如下所示:
假设有数组[a b c d e f g h]
一个大小为3的滑动窗口在其上滑动,则有:
1、单层循环
2、双层循环
模板只是一个解题思路,具体的题目可能需要具体分析,但是大体框架是不变的。
记住: 多刷题,多总结,是王道
1、最长不含重复字符的子字符串
2、绝对差不超过限制的最长连续子数组
3、无重复字符的最长子串
4、替换后的最长重复字符
滑动窗口算法就是用以解决数组/字符串的子元素问题
滑动窗口算法可以将嵌套的for循环问题,转换为单循环问题,降低时间复杂度
生命不止坚毅鱼奋斗,有梦想才是有意义的追求
给大家推荐一个免费的学习交流群:
最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。
Java开发交流君样:756584822
⑩ 经典C语言面试算法题
经典C语言面试算法题
1.写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
功能:
在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回
9,outputstr所指的值为123456789。
#include
#include
#include
int FindMax_NumStr(char *outputstr,char *inputstr)
{
char *in = inputstr,*out = outputstr,*temp;
char *final;
int count = 0;
int maxlen = 0;
int i;
while(*in!='