Java 常见常用算法详解

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
KMP28 实现 strStr()前缀表
位运算136 只出现一次的数字、191 位1的个数n & (n-1)
数学7 整数反转、9 回文数取余 / 数学公式

八、2026 年算法学习建议

  1. 刷题顺序推荐
  • 第一轮:LeetCode Hot 100(按标签刷)
  • 第二轮:剑指 Offer + 程序员面试金典
  • 第三轮:LeetCode 精选 200 + 公司题库(字节/阿里/美团)
  1. Java 实现注意点
  • 优先使用 ArrayDeque 代替 StackLinkedList
  • 优先使用 PriorityQueue(堆)
  • 字符串操作优先 StringBuilder
  1. 面试答题模板(强烈推荐):
  • 先说时间/空间复杂度
  • 再讲核心思想(双指针/动态规划/贪心…)
  • 给出代码框架
  • 最后说优化点 / 边界处理

需要我继续展开哪一块?

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

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

文章已创建 4758

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部