Java 常见常用算法详解(2026 最新版 · 面试 + 生产实用)

以下内容精选了 Java 开发和面试中出现频率最高、最实用的 20+ 个算法,按实际使用场景分类整理。每种算法都包含:

  • 核心思想
  • 时间/空间复杂度
  • Java 完整可运行代码(JDK 8+ 风格)
  • 适用场景 & 面试高频追问
  • 优化点

一、排序算法(面试必考 Top 3)

算法 时间复杂度(平均/最坏) 空间复杂度 稳定性 适用场景 推荐指数
快速排序 O(nlog n) / O(n²) O(log n) 不稳定 大数据量、综合性能最佳 ★★★★★
归并排序 O(nlog n) O(n) 稳定 链表排序、外部排序、稳定需求 ★★★★★
堆排序 O(nlog n) O(1) 不稳定 TopK、优先队列 ★★★★☆
1. 快速排序(Quick Sort)—— 最常用
public static void quickSort(int[] arr, int left, int right) {
    if (left >= right) return;
    
    int pivot = partition(arr, left, right);  // 选基准并分区
    quickSort(arr, left, pivot - 1);
    quickSort(arr, pivot + 1, right);
}

private static int partition(int[] arr, int left, int right) {
    int pivot = arr[right];   // 选最右为基准(可随机优化)
    int i = left - 1;
    
    for (int j = left; j < right; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(arr, i, j);
        }
    }
    swap(arr, i + 1, right);
    return i + 1;
}

private static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

优化技巧(面试加分)

  • 三数取中选基准
  • 小数组切换插入排序
  • 随机化基准(int pivotIndex = left + random.nextInt(right - left + 1);
2. 归并排序(Merge Sort)
public static void mergeSort(int[] arr, int left, int right) {
    if (left >= right) return;
    int mid = left + (right - left) / 2;
    mergeSort(arr, left, mid);
    mergeSort(arr, mid + 1, right);
    merge(arr, left, mid, right);
}

private static void merge(int[] arr, int left, int mid, int right) {
    int[] temp = new int[right - left + 1];
    int i = left, j = mid + 1, k = 0;
    
    while (i <= mid && j <= right) {
        temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
    }
    while (i <= mid) temp[k++] = arr[i++];
    while (j <= right) temp[k++] = arr[j++];
    
    System.arraycopy(temp, 0, arr, left, temp.length);
}

二、查找算法

算法 时间复杂度 适用条件 推荐指数
二分查找 O(log n) 有序数组 ★★★★★
线性查找 O(n) 无序小数组 ★★★☆☆
二分查找(Binary Search)模板(必须背熟)
// 查找第一个 >= target 的位置(左边界)
public static int lowerBound(int[] arr, int target) {
    int left = 0, right = arr.length;
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    return left;
}

三、双指针 / 滑动窗口(2026 年高频)

经典滑动窗口模板(固定 + 动态)

// 动态窗口:最长无重复子串
public int lengthOfLongestSubstring(String s) {
    Map<Character, Integer> window = new HashMap<>();
    int left = 0, maxLen = 0;
    
    for (int right = 0; right < s.length(); right++) {
        char c = s.charAt(right);
        window.put(c, window.getOrDefault(c, 0) + 1);
        
        while (window.get(c) > 1) {   // 收缩左边界
            char d = s.charAt(left);
            window.put(d, window.get(d) - 1);
            left++;
        }
        maxLen = Math.max(maxLen, right - left + 1);
    }
    return maxLen;
}

四、链表经典算法

反转链表(迭代 + 递归)
// 迭代版(最常用)
public ListNode reverseList(ListNode head) {
    ListNode prev = null, curr = head;
    while (curr != null) {
        ListNode next = curr.next;
        curr.next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}
快慢指针经典用法
  • 找链表中点:快慢指针
  • 判断环:Floyd 判圈法
  • 删除倒数第 N 个节点

五、树与二叉树

前中后序遍历(递归 + 非递归)

// Morris 遍历(空间 O(1))—— 面试加分神器
public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    TreeNode cur = root;
    while (cur != null) {
        if (cur.left == null) {
            res.add(cur.val);
            cur = cur.right;
        } else {
            TreeNode prev = cur.left;
            while (prev.right != null && prev.right != cur) {
                prev = prev.right;
            }
            if (prev.right == null) {
                prev.right = cur;
                cur = cur.left;
            } else {
                prev.right = null;
                res.add(cur.val);
                cur = cur.right;
            }
        }
    }
    return res;
}

六、动态规划入门(最常考)

经典 01 背包

public int knapsack(int[] weights, int[] values, int capacity) {
    int n = weights.length;
    int[] dp = new int[capacity + 1];
    
    for (int i = 0; i < n; i++) {
        for (int j = capacity; j >= weights[i]; j--) {
            dp[j] = Math.max(dp[j], dp[j - weights[i]] + values[i]);
        }
    }
    return dp[capacity];
}

七、其他高频算法速查表

算法类型 经典题目(LeetCode) 核心技巧
贪心 455 分发饼干、122 买卖股票 局部最优 → 全局最优
并查集 200 岛屿数量、547 省份数量 Union-Find + 路径压缩
拓扑排序 207 课程表 Kahn / DFS
KMP 28 实现 strStr() 前缀表
位运算 136 只出现一次的数字、191 位1的个数 n & (n-1)
数学 7 整数反转、9 回文数 取余 / 数学公式

八、2026 年算法学习建议

  1. 刷题顺序推荐

    • 第一轮:LeetCode Hot 100(按标签刷)
    • 第二轮:剑指 Offer + 程序员面试金典
    • 第三轮:LeetCode 精选 200 + 公司题库(字节/阿里/美团)
  2. Java 实现注意点

    • 优先使用 ArrayDeque 代替 StackLinkedList
    • 优先使用 PriorityQueue(堆)
    • 字符串操作优先 StringBuilder
  3. 面试答题模板(强烈推荐):

    • 先说时间/空间复杂度
    • 再讲核心思想(双指针/动态规划/贪心…)
    • 给出代码框架
    • 最后说优化点 / 边界处理

需要我继续展开哪一块?

  • 排序算法全家桶(7 大排序完整代码 + 动画描述)
  • 动态规划专题(背包、股票、子序列、区间 DP)
  • 图论算法(BFS/DFS/Dijkstra/Floyd/拓扑排序)
  • 字符串专题(KMP + Manacher + 滑动窗口)
  • LeetCode 高频 50 题 Java 模板合集

告诉我你的重点,我立刻给你最详细的代码 + 解析!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐