跳转至

暴力搜索

暴力搜索是算法入门中最基础的方法之一。

核心思想:

把所有可能情况逐个尝试,找到满足条件的答案。

也就是:

  • 全部试一遍
  • 不遗漏情况
  • 找到符合条件的结果

很多题目的第一思路,就是暴力搜索。

2. 为什么暴力搜索重要

虽然叫“暴力”,但它非常实用。

  • 数据范围小,直接暴力即可
  • 想不到优化时,先写暴力版本
  • 很多高级算法由暴力优化而来
  • DFS、回溯、本质上也是搜索

所以暴力搜索是基础能力。

3. 常见形式

枚举所有数

例如找 1~100 中能被 7 整除的数:

for(int i = 1; i <= 100; i++)
{
    if(i % 7 == 0)
        cout << i << " ";
}

双重枚举

找所有满足条件的数对:

for(int i = 0; i < n; i++)
{
    for(int j = i + 1; j < n; j++)
    {
        if(a[i] + a[j] == 10)
            cout << i << " " << j << endl;
    }
}

递归搜索

例如全排列、走迷宫、组合问题等。

4. 如何判断能不能暴力

先看数据范围。

如果 n 很小

例如:

n <= 20

通常可以枚举所有状态。

如果 n 中等

例如:

n <= 1000

通常可以使用双循环或部分搜索。

如果 n 很大

例如:

n <= 1e5

纯暴力通常会超时,需要优化。

5. 常见复杂度

写法 复杂度
单循环 O(n)
双循环 O(n²)
三循环 O(n³)
子集枚举 O(2ⁿ)
全排列 O(n!)

6. 示例:找最大值

int mx = a[0];

for(int i = 1; i < n; i++)
{
    if(a[i] > mx)
        mx = a[i];
}

逐个比较,找到最大值。

7. 示例:判断质数

bool prime(int x)
{
    if(x < 2) return false;

    for(int i = 2; i < x; i++)
    {
        if(x % i == 0)
            return false;
    }

    return true;
}

本质也是暴力尝试所有因子。

8. 常见优化方式

剪枝

当前情况已经不可能成功,就停止搜索。

去重

避免重复枚举相同情况。

预处理

例如前缀和、哈希表。

排序后处理

减少无意义判断。

9. 常见错误

漏情况

边界没枚举完整。

重复计算

同一种情况算了两次。

超时

数据很大还使用多重循环。

10. 比赛中的正确思路

第一步

先想暴力是否可做。

第二步

先写出正确答案。

第三步

再思考优化。

这是很常见的实战策略。

11. 一句话理解

暴力搜索 = 把所有可能答案试一遍。

12. 总结

暴力搜索不是笨办法。

它是很多高级算法的起点,能训练你的:

  • 枚举能力
  • 复杂度意识
  • 代码实现能力
  • 优化思维