滑动窗口算法:从暴力枚举到线性扫描的效率革命
在一个长度为 100 万的数组中找出连续 k 个元素的最大和。最直观的思路是:对每个可能的起始位置,累加 k 个元素,记录最大值。这需要大约 100 万次循环,每次循环内部还要遍历 k 个元素——总的时间复杂度是 $O(n \times k)$。 ...
在一个长度为 100 万的数组中找出连续 k 个元素的最大和。最直观的思路是:对每个可能的起始位置,累加 k 个元素,记录最大值。这需要大约 100 万次循环,每次循环内部还要遍历 k 个元素——总的时间复杂度是 $O(n \times k)$。 ...
Jon Bentley 在他的经典著作《Programming Pearls》中记录了一个令人震惊的实验结果:在贝尔实验室和 IBM 的课程中,他给专业程序员几个小时的时间实现二分查找,结果超过 90% 的人写出了有 bug 的代码。更令人惊讶的是,二分查找算法首次发表于 1946 年,但第一个正确的实现直到 1962 年才出现——整整 16 年间,这个看似简单的算法一直以"错误"的形式流传。 ...
假设你面前有一组从小到大排好序的数字,需要找出其中任意两个数之和等于目标值的组合。最直观的想法是嵌套两层循环,逐一尝试所有配对——时间复杂度 $O(n^2)$,当数据量达到十万级别时,程序开始变得迟缓。 ...
当你第一次尝试实现斐波那契数列时,可能会写出这样的递归代码: public int fib(int n) { if (n <= 1) return n; return fib(n - 1) + fib(n - 2); } 这段代码看起来简洁优雅,但当 n 达到 50 时,程序会运行很长时间才能返回结果。问题出在哪里?重复计算。计算 fib(5) 时会调用 fib(3),计算 fib(4) 时又会再次调用 fib(3)。随着 n 增大,重复计算的次数呈指数级增长——时间复杂度高达 $O(2^n)$。 ...