算法思想
🎯 学会这篇文章,我能做什么事情?实际上有什么帮助?用一段话来描述(100字左右)
掌握这篇文章中的算法思想,前端小白可以更好地理解和解决复杂问题,如页面数据处理、动画状态管理和性能优化。文章用简单示例和口语化讲解,帮助你轻松入门递归、分治、贪心、动态规划和双指针技巧,让你在写代码时更加自信和高效。
🌀 递归与迭代
递归和迭代是两种解决问题的基本思路。递归就是函数自己调用自己,像穿越迷宫一样,一步步往里走;迭代则是通过循环,一次次重复做相同的事情。
比如,计算 1 到 n 的和。
递归思路是拆成 n + (1 到 n-1 的和),代码如下:
function sumRecursive(n) {
if (n === 1) return 1;
return n + sumRecursive(n - 1);
}
console.log(sumRecursive(5)); // 15
迭代的做法是用循环累加:
function sumIterative(n) {
let total = 0;
for (let i = 1; i <= n; i++) {
total += i;
}
return total;
}
console.log(sumIterative(5)); // 15
🪓 分治思想
分治是一种“拆分问题,分别解决,再合并结果”的思想。适合处理复杂问题,比如排序。
举个例子,快速排序(Quick Sort)就是分治的典型应用。
原理:
- 选一个基准值(pivot)
- 把数组分成比基准值小和大的两部分
- 递归对这两部分分别排序
- 合并结果
示例代码:
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[0];
const left = [];
const right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) left.push(arr[i]);
else right.push(arr[i]);
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
console.log(quickSort([3, 6, 2, 8, 4])); // [2,3,4,6,8]
💰 贪心算法
贪心算法的核心就是:每一步都选择局部最优解,希望最终得到全局最优。
比如,最简单的找零钱问题,假设零钱有 10 元、5 元和 1 元,要找 18 元零钱。
贪心算法会先拿最大面额:
- 拿一张 10 元,剩 8 元
- 拿一张 5 元,剩 3 元
- 拿三张 1 元,剩 0 元
代码示例:
function getChange(amount) {
const coins = [10, 5, 1];
const result = [];
for (let coin of coins) {
while (amount >= coin) {
amount -= coin;
result.push(coin);
}
}
return result;
}
console.log(getChange(18)); // [10, 5, 1, 1, 1]
🧩 动态规划入门
动态规划(Dynamic Programming,简称 DP)是优化递归的一种方法,适合解决有重叠子问题和最优子结构的问题。
举个例子,经典的斐波那契数列:
function fib(n) {
const dp = [0, 1];
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
console.log(fib(10)); // 55
动态规划把之前算过的结果保存起来,避免重复计算。
🧮 双指针滑动窗口
双指针是一种用两个索引(指针)在数组或字符串上移动来解决问题的技巧。
滑动窗口是双指针的变种,常用来处理子串或子数组问题。
举个例子,找字符串中最长的不含重复字符的子串长度。
思路是用两个指针维护一个窗口,不断移动右指针,同时调整左指针保证窗口内字符无重复。
示例代码:
function lengthOfLongestSubstring(s) {
let left = 0;
let maxLen = 0;
const map = new Map();
for (let right = 0; right < s.length; right++) {
const char = s[right];
if (map.has(char) && map.get(char) >= left) {
left = map.get(char) + 1;
}
map.set(char, right);
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
console.log(lengthOfLongestSubstring('abcabcbb')); // 3
🧾 小节总结
- 递归与迭代是解决问题的基础,两者可根据需求选择
- 分治把复杂问题拆解成小问题,便于解决排序等任务
- 贪心算法每步选最优,简单快速但不总是最优解
- 动态规划通过保存中间结果避免重复计算,适合复杂状态计算
- 双指针滑动窗口技巧高效查找字符串和数组的子区间
❓ 知识问答(Q&A)
Q:递归和迭代有什么优缺点?
A:递归代码简洁,适合表达树形结构或分治;但可能导致栈溢出。迭代更节省内存,效率高,但代码有时较复杂。
Q:分治和动态规划有什么区别?
A:分治把问题拆成互相独立的小问题,动态规划适合有重叠子问题且要重复利用子结果的问题。
🎉 恭喜你已经掌握 递归与迭代、分治思想、贪心算法、动态规划入门、双指针滑动窗口 技能啦!继续练习,你会成为前端算法高手!
