前言
面试中算法基本上是必不可少的一个环节,现在面试环节基本分为三步,基础知识丶项目丶算法,这里主要汇总一下常见的算法题,目前大部分的面试算法题都能覆盖到
1.链表篇
2.树
3.数组
4.topN
1.使用最大堆的方式实现,在Java中,我们可以使用PriorityQueue
来实现最大堆
public class TopN {
public static void main(String[] args) {
int[] data = {3, 1, 5, 7, 2, 4, 9, 6, 8, 0};
int n = 3; // 获取Top 3元素
// 创建一个最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
// 插入元素
for (int num : data) {
maxHeap.offer(num);
}
// 获取Top N元素
System.out.print("Top " + n + " elements: ");
for (int i = 0; i < n; i++) {
System.out.print(maxHeap.poll() + " ");
}
}
}
使用list实现
public static void main(String[] args) {
int[] arry = {21,3,12,32,12,54,65,23,959,32,124,3235,0,21,43,45,12,1,43,345,43,63,12,57,462,35,965,32,142,45};
List<Integer> list = new ArrayList<Integer>();
for(int i = 0;i < arry.length; i++) {
//如果当前链表大小小于10,则直接进行插入
if(list.size()<10) {
put(list,arry[i]);
continue;
}
//如果数字大于链表的首位。则不进行后续操作
if(arry[i] > (int)list.get(0))
continue;
put(list,arry[i]);
}
System.out.println(list.toString());
}
private static void put(List<Integer> list, int num) {
if(list.size() < 10) {
list.add(num);
Collections.sort(list);
Collections.sort(list,new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
return;
}
list.remove(0);
list.add(num);
Collections.sort(list,new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
}
5.字符串匹配
可以使用滑动窗口和kmp算法,这里用相对简单的滑动窗口
public static int bf(String ts, String ps) {
char[] t = ts.toCharArray();
char[] p = ps.toCharArray();
int i = 0; // 主串的位置
int j = 0; // 模式串的位置
while (i < t.length && j < p.length) {
if (t[i] == p[j]) { // 当两个字符相同,就比较下一个
i++;
j++;
} else {
i = i - j + 1; // 一旦不匹配,i后退
j = 0; // j归0
}
}
if (j == p.length) {
return i - j;
} else {
return -1;
}
}
6.字符串乘积
求两个字符串的乘积
public class Solution {
public String multiply (String num1, String num2) {
// write code here
int len_num1 = num1.length();
int len_num2 = num2.length();
// 长度为 len_num1 + len_num2 的结果数据,用来存放结算的乘积的值
int[] result = new int[len_num1 + len_num2];
Arrays.fill(result, 0);
/*
先不考虑进位问题,根据竖式的乘法运算,num1的第i位与num2的第j位相乘,结果应该存放在结果的第i+j位上
为了方便,从
*/
for (int i = len_num1 - 1; i >= 0; i--) {
for (int j = len_num2 - 1; j>= 0; j--) {
// 因为 num1 、num2 的高位都是从 0 开始数的,所以存储结果的时候,存在 i + j + 1 的索引下
result[i + j + 1] += (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
}
}
// 单独处理 result 中的进位问题. 从低位 --> 高位 (从 result 的 右 -> 左)
for (int i = result.length - 1; i > 0; i--) {
if (result[i] >= 10) {
result[i -1] += result[i] / 10;
result[i] %= 10;
}
}
// int[] -> String
StringBuffer sb = new StringBuffer();
int i = 0;
while (result[i] == 0 && i < result.length - 1) {
i ++;
}
while (i < result.length) {
sb.append(result[i++]);
}
return sb.toString();
}
}
7.多线程顺序打印字母abc
这也是道比较常见的题了,之前面字节的时候被问到过
public class SortPrintAlphabet {
static Object syn = new Object();
public static String next = "a";
public static void main(String[] args) {
new SortPrintAlphabet().print();
}
private void print(){
ExecutorService service = Executors.newFixedThreadPool(3);
service.execute(new APrinThread());
service.execute(new BPrinThread());
service.execute(new CPrinThread());
}
class APrinThread implements Runnable{
@Override
public void run() {
while(true){
synchronized (syn) {
while(!"a".equals(next)){
try {
syn.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.print("a");
next = "b";
syn.notifyAll();
}
}
}
}
class BPrinThread implements Runnable{
@Override
public void run() {
while(true){
synchronized (syn) {
while(!"b".equals(next)){
try {
syn.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.print("b");
next = "c";
syn.notifyAll();
}
}
}
}
class CPrinThread implements Runnable{
@Override
public void run() {
while(true){
synchronized (syn) {
while(!"c".equals(next)){
try {
syn.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("c");
next = "a";
syn.notifyAll();
}
}
}
}
}
8.算法相关
8.1 书籍
《数据结构与算法之美》 优先级高(速成)
《数据结构与算法分析:Java语言描述》 优先级高(筑基)
8.2 刷题
覃超 《算法面试通关 40 讲》 优先级高(速成)
- 覃超 《算法面试通关 40 讲》 优先级高(速成)
- 左神 《牛客算法系列》
- 小象学院 《面试算法 LeetCode 刷题班》
- 左神 《程序员代码面试指南:IT 名企算法与数据结构题目最优解(第二版)》
- 何海涛 《剑指 Offer:名企面试官精讲典型编程题》
- 《编程之美:微软技术面试心得》
8.3 哪些题目
正如我们在 《花花酱 LeetCode进入千题时代后该如何刷题?》 看到的视频,我们需要每个类型的 10-20 题,所以我们需要知道,算法面试,主要有哪些题型,每个题型刷哪些题目。
题型来说,我们可以按照数据结构与算法分别分类:
- 数据结构
- 数组
- 链表
- 栈和队列
- 字符串
- 哈希表(散列表)
- 树
- 堆
- 图
- 算法
- 双指针
- 排序
- 二分查找
- 深度优先搜索
- 广度优先搜索
- 拓扑排序
- 并查集
- 分治算法
- 回溯算法
- 贪心算法
- 动态规划
- 位运算
- 数学