当前位置:首页 » 操作系统 » 典型算法题

典型算法题

发布时间: 2023-05-13 14:13:01

‘壹’ 面试最常考的 100 道算法题分类整理

大家好,我是 “负雪明烛” ,一位用 7 年写了 1000 篇 LeetCode 算法题题解的程序员。欢迎关注。

粉丝常说: LeetCode 算法题太多了,准备面试该刷哪些题目

我之前根据 LeetCode 上面的点赞量分享过: LeetCode 上最经典的 100 道算法题 。

这 100 道题目都属于经典题目了,面试也常考,不过我还是不放心呢,毕竟 经典题 ≠ 面试题 呀!

但如果想知道面试常考的 100 道算法题的话,需要至少整理 1000 篇面经吧?这个工作量可不小啊!

还好,网上有个开源项目,帮我们做了这件事情,这个项目就是 CodeTop

这是网站的界面(地址: https://codetop.cc/home ),展示的就是每个面试题目出现的频度情况,甚至区分了公司和岗位:

这是开源项目的 GitHub 主页,已经 11.5k star ⭐️ 了:

这个项目中的题目来源是牛客网的面经、网友投票等,而且持续更新中,所以还是比较可靠的。

我对这个项目做了整理,分类整理出来面试常考的 100 道算法题。

在整理之后,我对结果还是有点 惊讶 的!因为一些常见的数据结构与算法,竟然没有在常考面试中出现过!

比如前缀和、前缀树、并查集、图,这些都没有出现……

最常考面试题还是很基本的链表、二叉树、动态规划等等,是不是符合你的认知呢?

强烈建议大家在面试前把这 100 道题目搞懂!

作为宠粉达人,我提供了 3 种方式查看这 100 道题目:

没有任何套路,直接分享给大家!

在线查看地址: https://www.mubucm.com/doc/7jiBYKCKqet

在线查看地址: https://leetcode-cn.com/problem-list/q3iOID0B/

所有题目的地址如下:

前序遍历

中序遍历

层序遍历

视图

如果你觉得对你有帮助的话,求赞、求分享、求收藏。你的每一点鼓励都是对我的最大帮助!

‘贰’ java经典算法题——猴子吃桃

public class Monkey
{
public static void main(String[] args)
{
int sum=0,remain=1;
//每天吃剩的桃子加一个正好是前一天桃子的一半,每天桃子的总数就是前一天剩下桃子的数量
for(int day=9;day>=1;day--)
{
sum=(remain+1)*2;
remain=sum;
System.out.println("第"+day+"天还剩"+remain+"个桃子");
}
System.out.println(sum);
}
}

‘叁’ 面试会出哪些经典算法题

1、排序算法∶快速排序、归并排序、计数排序

2、搜索算法∶回溯、递归、剪枝技巧

3、图论∶最短路、最小生成树、网络流建模

4、动态规划:背包问题、最长子序列、计数问题

5、基础技巧:分治、倍增、二分、贪心

6、数组与链表:单/双向链表、跳舞链

7、栈与队列

8、树与图:最近公共祖先、并查集

9、哈希表

10、堆:大/小根堆、可并堆

11、字符串∶字典树、后缀树

(3)典型算法题扩展阅读:

算法的重要性:

1、算法能力能够准确辨别一个程序员的技术功底是否扎实;

2、算法能力是发掘程序员的学习能力与成长潜力的关键手段;

3、算法能力能够协助判断程序员在面对新问题时,分析并解决问题的能力;

4、算法能力是设计一个高性能系统、性能优化的必备基础。

‘肆’ 面试会出哪些经典算法题

如下:

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年提出的图灵机。即使在当前,依然常有直觉想法难以定义为形式化算法的情况。

‘伍’ 经典算法题之兔子问题

就是那个递归算法:f(1)=1;f(2)=1;f(3)=2;...f(n)=f(n-1)+f(n-2);程序是:(计算任一月兔子数)long fun(int x){ int i; if(x==1 || x==2) return 1; else return fun(x-1)+fun(x-2);}void main(){ int i,a; long s; scanf("%d",&a); printf("%ld\n",fun(a)); }

‘陆’ 经典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!='')

{

if(*in > 47 && *in < 58)

{

for(temp = in;*in> 47 && *in <58;in++)

count++;

}

else

in++;

if(maxlen < count)

{

maxlen = count;

count = 0;

final = temp;

}

}

for(i =0;i

{

*out = *final;

out++;

final++;

}

*out = '';

return maxlen;

}

void main(void)

{

char input[]="abc123def123456eec123456789dd";

char output[50] = {0};

int maxlen;

maxlen = FindMax_NumStr(output,input);

printf("the str %s ",output);

printf("the maxlen is %d ",maxlen);

}

2.求1000!的未尾有几个0;

求出1->1000里,能被5整除的数的个数n1,能被25整除的数的个数n2,能被125整除的'数的个数n3,能被625整除的数的个数n4.1000!末尾的零的个数=n1+n2+n3+n4;

只要是末尾是5的数它乘以一个偶数就会出现一个0,而末尾是0的数乘以任何数也都会出现0

而末尾是0的如果是一个0肯定能被5整除,两个0肯定能被25整数,以此类推3个0就能被5的三次方整除,也就是125

1000!就是1-1000数的相乘,能被5整除的所有数分别乘以一个偶数就会出现这些个的0,而例如100,既能被5整除,也能被25整除,所以就是两个0

1000,既能被5,25,也能被125整除,所以算三个0

例如是10!=1*2*3*4*5*6*7*8*9*10,里面有两个数能被5整除,就是10和5,而

5随便乘以一个偶数就出现一个0,而10乘以其它数也会出现一个0,所以10!会有两个0

#include

#define NUM 1000

int find5(int num)

{

int ret = 0;

while(num%5==0)

{

num/=5;

ret++;

}

return ret;

}

int main(void)

{

int result = 0;

int i;

for(i=5;i<=NUM;i+=5)

result +=find5(i);

printf("the total zero number is %d ",result);

return 0;

}

3。编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的。

char * search(char *cpSource, char ch)

{

char *cpTemp=NULL, *cpDest=NULL;

int iTemp, iCount=0;

while(*cpSource)

{

if(*cpSource == ch)

{

iTemp = 0;

cpTemp = cpSource;

while(*cpSource == ch)

++iTemp, ++cpSource;

if(iTemp > iCount)

iCount = iTemp, cpDest = cpTemp;

if(!*cpSource)

break;

}

++cpSource;

}

return cpDest;

}

;

‘柒’ 大公司笔试面试有哪些经典算法题目

1、二维数组中的查找

具体例题:如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列, {1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。现在给出一个数字序列,允许使用一种转换操作:选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列?



‘捌’ 大公司笔试面试有哪些经典算法题目

1、二维数组中的查找

具体例题:如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列, {1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。现在给出一个数字序列,允许使用一种转换操作:选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列?



‘玖’ 经典算法题:分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评亏迹分销芦并。

你需要按照以下要求,给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。
相邻两个孩哗物子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:

输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:

输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。

提示:

n == ratings.length
1 <= n <= 2 * 104
0 <= ratings[i] <= 2 * 104

‘拾’ 算法题(三)

(1)定义两个变量,行变量row和列变量col

(2)利用while和if条件判。若是当前数小于target,row++;若是当前数大于target,col--。

(3)若搜索到相等,直接返回true

(4)若退出while后仍然没有返回,则返回false

注意:利用while,不用两层for,可以避免了整个二维数组的遍历

思路:利用一个新凳缓的StringBuffer。遍历原StringBuffer,若不为空格,直接加入新buffer尾部,否则append("%20")

思路:一个栈用来添加元素,一个栈用来弹出元素。重点是:在添加或弹出元素前,必须先弹出另一个栈的所有元素到当前栈。

思路:二分法。

    我们的目的是:当进行一次比较时,一定能够确定答案在mid的某一侧。一次答茄比较为 arr[mid]跟谁比的问题。

    一般的比较原则有:

        · 如果有目标值target,那么直接让arr[mid] 和 target 比较即可。

        · 如果没有目标值,一般可以考虑  端点

    这里我们把target 看作是 右端点 ,来进行分析,那就要分析以下三种情况,看是否可以达到上述的目标。

· 情况1,arr[mid] > target:4 5 6 1 2 3

    arr[mid] 为 6, target为右端点 3, arr[mid] > target, 说明[first ... mid] 都是 >= target 的,因为原始数组是非递减,所以可以确定答案为 [mid+1...last]区间,所以 first = mid + 1

· 情况2,arr[mid] < target:5 6 1 2 3 4

    arr[mid] 为 1, target为右端点 4, arr[mid] < target, 说明答案肯定不在[mid+1...last],但是arr[mid] 有可能是答案,所以答案在[first, mid]区间,所枣举模以last = mid;

· 情况3,arr[mid] == target:

    如果是 1 0 1 1 1, arr[mid] = target = 1, 显然答案在左边

    如果是 1 1 1 0 1, arr[mid] = target = 1, 显然答案在右边

    所以这种情况,不能确定答案在左边还是右边,那么就让last = last - 1;慢慢缩少区间,同时也不会错过答案。

思路:典型的递归。此外还可以用动态规划等。

思路:递归。

思路:从数学公式中看出的递归方法。

思路:递归,或记忆性递归。

思路:利用位运算,直接找到从右向左第一个1的位置

思路:利用两个队列,第一次遍历数组时,将奇数和偶数分别放入对应队列;第二次遍历两个队列,将元素放回数组

思路:按层打印,每个层用左上角和右下角两个点选中。

思路:两个栈,min栈每次保存当前栈元素的最小值

思路:定义一个栈,遍历数组A,对于每个元素,先压入栈,再循环弹出当前栈顶与数组B当前下标相同的元素。算法结束,若栈为空,则返回true。

思路:回溯

思路一:遍历数组,利用哈希表记录元素个数;再遍历哈希表,判断哪个元素个数超过一半

思路二:利用题目信息,直接排序数组,返回最中间元素即可。

思路:先排序,再取前k个数

思路一:动态规划

思路二:利用全局变量保存最大值,最大值为负数,直接置0,遍历数组往后加

思路:贪心算法。

(1)将原数组转为字符串存在list中

(2)自定义Comparator对List进行排序

(3)逐位比较两个字符串,若到达字符串尾部,返回首部继续比较。

(4)利用StringBuffer将List进项拼接,并返回结果。

思路:丑数能够分解成2^x 3^y 5^z,所以只需要把得到的丑数不断地乘以2、3、5之后并放入他们应该放置的位置即可。

(1)定义三个指针,分别代表2,3,5的个数

(2)每次取运算结果的最小值

(1)定义一个包含所有字符的数组,ASCII码(一个ASCII码长度是一个字节,也就是8个bit,最高位是0作为校验位,其余7位使用0和1进行组合,所以ASCII码共有128个)

(2)遍历字符,将每个字符作为下标,将数组对应下标值加1

(3)遍历字符串,找到第一个数组值为1 的下标返回

思路:利用归并排序的过程求解

思路:先利用二分查找找到该数的位置,再从该位置左右遍历相同的数并计数。

思路:哈希表或异或运算

思路:穷举法,双层遍历,找到了就加入结果集。

思路:双指针法

(1)初始化双指针为一头一尾

(2)若当前两数和小于S,则左指针右移;若大于S,则右指针左移;否则,输出结果。

思路一:利用标准库,s.substring()先进行字符串拆分,再进行拼接。

思路二:先转为字符数组,再借助辅助数组进行移位。

思路:先利用str.split(" ")将字符串按照空格分割为字符串数组,再利用数组移位或者是栈进行翻转。

思路:

(1)先排序数组

(2)遍历数组,记录数组中0的个数和不同非0数字之间的差值

(3)根据0的个数和差值进行判断

思路:递归,当我们知道了 f(n - 1, m) 对应的答案 x 之后,我们也就可以知道,长度为 n 的序列最后一个删除的元素,应当是从 m % n 开始数的第 x 个元素。

思路:递归

思路:注意越界问题即可。用布尔值记录正负号,再逐位计算。

思路:利用set进行遍历即可

思路一:利用一个栈,将元素顺序倒置。

思路二:正序遍历并保存元素至链表,利用Collections.reverse(list)反转链表。

思路:快慢指针,首先让快指针先行k步,然后让快慢指针每次同行一步,直到快指针指向空节点,慢指针就是倒数第K个节点。

思路:归并排序

思路:利用Map集合存储<链表节点,新建节点>,再遍历链表,建立新建链表之间的关系。

思路:这道题默认无环

(1)都无环:得到两个链表的长度,长链先走,再和短链一起走

(2)都有环:

        · 若入环点相同,同无环解法

        · 若入环点不同,从一个入环点往下遍历,在碰到自己之前碰到了另一个入环点,则返回该入环点;否则无相交点

其他情况都无相交点。

思路:递归。利用中序和前序中,根节点的位置进行划分左右子树。

思路:递归,选中结点递归是否是子树,若不是子树,再递归选中结点的左右节点查找子树。

思路:递归,DFS,先交换左右节点,再继续递归左右子节点

思路:利用队列,层序遍历,BFS。

思路:递归,根据元素大小进行左右递归分区,知道分区只剩一个元素或0个元素,往前返回。

思路:回溯,每个元素先加入,若满足条件,加入结果集,再遍历左右子树,然后回溯。

思路:先中序遍历结果存储在链表中,再遍历链表,连接左右指针。

思路:递归,递归过程中将左右子树的最大值加1;

思路:递归,递归中判断左右字数高度差

注意substring中没有单词大写!

    是String类中的方法

热点内容
数据库分页查询数据 发布:2025-05-15 15:45:13 浏览:519
phpmyadmin上传限制 发布:2025-05-15 15:39:52 浏览:430
如何给手机配置真正的电脑 发布:2025-05-15 15:39:52 浏览:763
抽脚本命令 发布:2025-05-15 15:39:45 浏览:659
sok编程 发布:2025-05-15 15:33:21 浏览:40
lms算法程序 发布:2025-05-15 15:31:53 浏览:569
数据库二级映射 发布:2025-05-15 15:14:09 浏览:477
3d文件加密 发布:2025-05-15 15:05:17 浏览:361
jquery拖拽上传图片 发布:2025-05-15 14:53:36 浏览:129
我的世界电脑服务器需要正版吗 发布:2025-05-15 14:38:53 浏览:695