前言

面试中算法基本上是必不可少的一个环节,现在面试环节基本分为三步,基础知识丶项目丶算法,这里主要汇总一下常见的算法题,目前大部分的面试算法题都能覆盖到

面试最常见算法汇总_算法汇总

1.链表篇

面试最常见算法2—链表

2.树

面试最常见算法1—树—基础篇

面试最常见算法1—树—进阶篇

3.数组

面试最常见算法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 讲》 优先级高(速成)

8.3 哪些题目

正如我们在 《花花酱 LeetCode进入千题时代后该如何刷题?》 看到的视频,我们需要每个类型的 10-20 题,所以我们需要知道,算法面试,主要有哪些题型,每个题型刷哪些题目。

题型来说,我们可以按照数据结构与算法分别分类:

  • 数据结构
  • 数组
  • 链表
  • 栈和队列
  • 字符串
  • 哈希表(散列表)
  • 算法
  • 双指针
  • 排序
  • 二分查找
  • 深度优先搜索
  • 广度优先搜索
  • 拓扑排序
  • 并查集
  • 分治算法
  • 回溯算法
  • 贪心算法
  • 动态规划
  • 位运算
  • 数学