程序员必备数学知识

36 阅读4分钟

程序员必备数学知识

📚 核心内容(按重要性排序)

  1. 对数 log n - 复杂度分析
  2. 指数与幂运算
  3. 位运算
  4. 等差/等比数列
  5. 模运算

1. 对数 log n - 复杂度分析

核心概念

log₂(n) 就是问:2的几次方等于n?

听起来抽象,但你每天都在用。

必记数值

这些数字背下来,分析复杂度快很多:

nlog₂(n)实际意义
422次比较找到目标
833次比较找到目标
1024101KB数据,10次比较搞定
1,000,000~20百万数据,20次就够了

两个关键公式

记住这两个,化简复杂度够用了:

log(a × b) = log(a) + log(b)    # 乘法变加法
log(aⁿ) = n × log(a)              # 指数拿出来

为什么重要?

  • 二分查找:每次砍一半,复杂度是 O(log n)
  • 平衡树:树的高度就是 log n,查找飞快
  • 归并排序:每层 O(n),总共 log n 层 → O(n log n)

2. 指数与幂运算

核心概念

2ⁿ 告诉你数据量增长有多快。

必记数值

表达式结果实际含义
2¹⁰1,0241KB,千这个量级
2²⁰1,048,5761MB,百万级
2³¹-12,147,483,647int最大值(21亿)
2³²4,294,967,29642亿

常见量级

2¹⁰ = 1千(1KB)
2²⁰ = 100万(1MB)
2³⁰ = 10亿

3. 位运算

基本操作

&   // 与:两个都是1才是1
|   // 或:有一个是1就是1
^   // 异或:相同是0,不同是1
~   // 取反:0变1,1变0
<<  // 左移:乘以2
>>  // 右移:除以2

常用技巧

// 判断奇偶
x & 1 == 1      // 奇数

// 判断2的幂
(n & (n-1)) == 0

// 找唯一数字(LeetCode 136)
// [2,3,2,4,4] → 3
int result = 0;
for (int num : nums) {
    result ^= num;  // 相同的数异或抵消
}

4. 等差/等比数列

等差数列

公式:1+2+3+...+n = n×(n+1)/2

用来算嵌套循环次数:

for (int i = 0; i < n; i++) {
    for (int j = 0; j < i; j++) {
        // 跑了 0+1+2+...+(n-1) = n(n-1)/2 次
        // 复杂度 O(n²)
    }
}

等比数列

规律:n + n/2 + n/4 + ... ≈ 2n

每次减半,加起来也就2倍。

例子:16 + 8 + 4 + 2 + 1 = 3132

应用:归并排序每层n个数,log n层 → O(n log n)


5. 模运算

核心概念

a % b = a 除以 b 的余数

防溢出

大数运算先取模:

// 错误:先乘后模可能溢出
int result = (a * b) % MOD;

// 正确:先模后乘
int result = ((a % MOD) * (b % MOD)) % MOD;

常见用途

  • 哈希表hash(key) % size 定位槽位
  • 循环队列(index + 1) % capacity 实现循环

📊 时间复杂度速查表

从快到慢排个序,一眼就能看出性能:

复杂度速度典型场景
O(1)超快数组取值、哈希查找
O(log n)很快二分查找、平衡树
O(n)正常遍历数组
O(n log n)还行快排、归并排序
O(n²)有点慢冒泡排序、双层循环
O(2ⁿ)慢到爆暴力递归、枚举子集

记住:从上到下越来越慢,O(2ⁿ) 基本上就是放弃治疗了。


💡 程序员必记数值

# 2的幂
2¹⁰ = 1024        → 1KB
2²⁰ = 104万        → 1MB
2³¹-1 = 21亿       → int最大值

# 数量级
10³ = 1千
10⁶ = 100万
10⁹ = 10亿

🎯 实战速查

如何判断算法复杂度?

一眼看懂代码跑多快:

// O(1) - 常数时间
// 不管数据多大,都是一次操作
arr[i] = 1;

// O(log n) - 对数时间
// 二分查找,每次砍一半
public int binarySearch(int[] arr, int target) {
    int left = 0, right = arr.length - 1;
    while (left <= right) {
        int mid = (left + right) / 2;
        // ...
    }
}

// O(n) - 线性时间
// 遍历一遍
for (int i = 0; i < n; i++) {
    // ...
}

// O(n²) - 平方时间
// 嵌套循环
for (int i = 0; i < n; i++) {
    for (int j = 0; j < i; j++) {
        // ...
    }
}

// O(2ⁿ) - 指数时间(危险!)
// 递归会炸掉
public int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}

如何优化?

看数据范围就知道能不能过:

复杂度数据范围能否接受?
O(n log n)n ≤ 10⁶✅ 稳过
O(n²)n ≤ 10³✅ 勉强能过
O(n²)n ≤ 10⁴❌ 铁定超时
O(2ⁿ)n ≤ 20✅ 刚好能过
O(2ⁿ)n ≤ 30❌ 别想了,换算法

🔑 总结

这5项必须掌握:

  1. log n - 搞懂二分和分治的底层原理
  2. 2的幂 - 判断数据规模,估算内存占用
  3. 位运算 - 让代码跑得更快,省下更多空间
  4. 数列求和 - 快速分析时间复杂度
  5. 模运算 - 防止计算溢出,哈希表的基础

数学不是为了装逼,是为了写出高效代码。这些知识掌握了,你就能一眼看出算法的性能瓶颈,面试的时候也能把面试官唬住。