70道面试常见算法题

  1. 字符串的循环移位
    三次翻转

  2. 字符串的包含
    哈希表

  3. 字符串全排列
    next_permutation算法

  4. 字符串的所有组合
    dfs

  5. 字符串转整数
    stoi(), stol(), 注意边界

  6. 回文判断:判断字符串是否为回文串
    双指针从两头往中间扫描

  7. 判断链表是否回文
    (1)快慢指针找中点(2)翻转后半部分(3)遍历比较两段链表

  8. 判断栈是否回文
    出栈后再入栈,与原字符串比较是否完全相同

  9. 最长回文子串
    manacher算法:(1)预处理(2)id记录最远回文串中心,mx记录最远回文串位置
    扩展KMP:比较原串的后缀与翻转串的前缀的最长公共前缀

  10. 最长重复出现子串
    next[]数组的最大值

  11. 最长公共子串
    动态规划:
    扩展KMP:

  12. 寻找最小的K个数
    排序,最小堆,partition算法

  13. 寻找和为定值的两个数
    对于已排序的数组,可以双指针两头扫描

  14. 寻找二叉树中和为定值的从根节点出发的所有路径
    dfs+剪枝

  15. 寻找和为定值的四个数
    枚举+二分

  16. 寻找和为定值的多个数
    转化为01背包问题

  17. 最大连续子数组和
    动态规划:maxSum记录最大和,curSum记录当前和,当curSum小于0时重置为当前元素值

  18. 最大子矩阵和
    动态规划:枚举i行到j行范围,类比最大连续子数组和,求出行范围内从第0列到第k列的总和curSum,当curSum小于0时重置为当且列的和

  19. 跳台阶问题
    斐波那契递推

  20. 换硬币问题:100元钱,有1元,2元,5元,10元面值的硬币,有多少种换法
    完全背包问题

  21. 奇偶数排序:奇数放在前面,偶数放在后面,可改变相对顺序
    双指针

  22. 荷兰国旗问题:数组只含0,1,2,要求0排最前,1排中间,2排最后
    三指针,类比快排算法

  23. 唯一重复的元素
    正负标记法

  24. 三个只出现一次的数:有三个数只出现一次,其余数均出现两次,找出这三个数
    哈希

  25. 两个只出现一次的数:有两个数只出现一次(或奇数次),其余数均出现两次(或偶数次),找出这两个数
    全部异或,根据异或的1比特位进行分类,再分别异或

  26. n个整数中1出现的次数
    动态规划保存结果

  27. 寻找接近给定和的若干个数
    负数转正数,转化为背包问题

  28. 寻找和为定值的连续子数组
    前缀和+哈希

  29. 寻找直方图中面积最大的矩形
    类比接雨水,单调栈

  30. 串中取串:n个数,求出子串中数字和mod 3 = 0的串
    尺取法

  31. 从一列数中删除尽可能少的数,使得数组变成山脉数组
    动态规划,dp1[i]表示以i结尾的最长递增串长度,dp2[i]表示以i开头的最长递减串长度

  32. 波浪数组查找某个数
    扩展二分

  33. 最长递减子序列
    朴素dp:
    队列优化:

  34. 数字映射:下排的每个数都是上排的对应数字在下排出现的次数。
    0:n-4次,1:2次,2:1次,n-4:1次

  35. 数组分割:数组长度为n,分割成m份,要求各份的和相等,求m的最大值。
    二分查找

  36. 旋转数组的最小值
    同构字符串的最小表示

  37. 鸡蛋放篮子:n个鸡蛋放到m个篮子,篮子不能为空,要满足对于任意不大于n的数量,能用若干个篮子的鸡蛋的总数表示。求所有满足条件的放法。
    dfs,让篮子鸡蛋数递增,保证从小到大的所有数都能表示出来

  38. 数组分裂:n个元素的数组,分割成两组,使得两组的和的差绝对值最小
    01背包问题

  39. 合并两个排序数组
    双指针

  40. 数组的等和问题:n个元素,取m个,使得m个数的和等于另外n-m个数的和
    背包问题

  41. 任务的分配:n个任务委派给n个人,每个人做的不同任务的花费为cost[i][j],求总花费最小的分配方式。
    匈牙利算法、二部图的完美匹配。

  42. 站点之间的距离:已知相邻站点间的距离,高效地求任意站点间地距离
    前缀和

  43. 数组的逆序对个数
    归并排序衍生:
    树状数组:先离散化,对于每个数,求出范围内前缀和,然后向树状数组添加这个数

  44. 格子涂色
    动态规划

  45. 鸡蛋掉落问题
    动态规划+记忆化搜索+二分:dp(K, N) = 1 + min(max(dp(K - 1, X - 1), dp(K, N - X)))
    在X层蛋碎,则往下找;在X层蛋未碎,则往上找。

  46. 统计出现次数最多的数据
    hash_map,map等

  47. 上亿行数据的快速查询
    B树、B+树

  48. 二叉树节点的最近公共祖先(LCA)
    dfs求路径:比较最后一个公共元素
    线段树:预处理+查询

  49. 求二叉树节点的最大距离
    两次dfs:
    直接递归:

  50. 求二叉树的深度
    dfs

  51. 树节点的和:给定二叉树,每个节点的值都是整数,找到一个子树使它的和最大。
    后序遍历:

  52. O(1)空间遍历二叉树
    Morris遍历法:

  53. 行列递增矩阵的查找
    分治法:在对角线二分查找,然后在左下和右上两个矩阵分别查找
    定位法:从右上角开始,若比target大就往左,若比target小就往下

  54. 出现次数超过一半的数
    动态规划:curAns和curCnt,与curAns相同则curCnt++;否则curCnt–;若curCnt减为0,则更行curAns。

55. 字符串模式匹配:KMP

void getNxt() {
	memset(nxt, 0, sizeof(nxt));
	nxt[0] = -1;
	int j = 0, k = -1;
	while (j < n) {
		if (k == -1 || str[k] == str[j]) {
			j++, k++;
			nxt[j] = k;
		} else k = nxt[k];
	}
}
int kmp(void) {
	int cnt = 0;
	getNxt();
	int i = 0, j = 0;
	while (i < n) {
		if (j == -1 || T[i] == W[j]) i++, j++;
		else j = nxt[j];
		if (j >= m) j = nxt[j], cnt++;
	}
	return cnt;
}
  1. 最大连续乘积子数组
    动态规划:同时记录最大值mx和最小值mi,遇到负数则交换两者

  2. 字符串编辑距离(任意位置插入,替换,删除)
    动态规划:dp[i][j]表示S[0i]到T[0j]的最短编辑距离,则
    dp[i][j] = min { dp[i-1][j] + 1, S[i]不在T[0~j]中;
    dp[i-1][j-1] + 1/0, S[i]在T[j]中,当S[i]==T[j]时取0;
    dp[i][j-1] + 1, S[i]在T[0~j-1]中 }

  3. 格子取数问题
    动态规划:类比数塔问题

  4. 骨牌问题(1*2骨牌平铺)
    边界dp

  5. Tire树

  6. 找到链表倒数第n个元素
    先后指针

  7. 判断两个无环链表是否相交
    是否相交:判断尾节点是否相同即可
    找到第一个交点:根据长度,设先后指针

  8. 判断链表是否有环
    是否有环:快慢指针
    找到环的起点:在相遇点和起点再设两个同步指针,一定会在入口点相遇

  9. 全零矩阵:对矩阵某个元素加一时,其周围四个元素也会加一,能否得到指定整数矩阵
    开关问题:枚举第一行状态,接下来每一行都与上一行有关

  10. 设计min栈:一个栈保存值,一个栈保存最小值

  11. 两个栈实现队列:一个栈负责入,一个栈负责出

  12. 八皇后问题:dfs

  13. 最小生成树:prim,kruskal

  14. 蚂蚁爬杆:弹性碰撞化为穿越

  15. 跑道赛马:5条跑道,每条跑道最多跑一匹马,25匹马最少比赛多少次可以比出最快的5匹马?
    首先要至少比赛5+1次,得出杨氏矩阵,然后具体情况具体分析。

你可能感兴趣的:(CS考研复试)