思想
数据结构与算法大约 4 分钟...
穷举
计算机没有归纳总结,逻辑推理的能力,完成一些重复的工作是计算机最擅长的,穷举法就是利用这一特点产生的思想,顾名思义,根据条件确定答案的大致范围,然后对此范围内的所有情况逐一验证,直到全部情况验证完毕,最后可得出该题目是否有解
比如求出某些范围内能被 3 整除也能被 5 整除的数字,即可用穷举法
function resolve(num) {
const arr = [];
for (let i = 1; i <= num; i++) {
if(i % 3 == 0 && i % 5 == 0) {
arr.push(i);
}
}
return arr;
}
分而治之
分而治之是一种非常重要的算法设计思想,它通常包含以下三个步骤:
- 分解:将一个大问题分解成多个更小的子问题。子问题应该彼此独立,并且可以用相同的方法解决
- 解决:递归地解决每个子问题。对于较小的子问题,可以直接使用简单的解决方法
- 合并:将子问题的解决方案组合起来,得到原问题的解决方案。合并过程可能需要一些额外的处理或运算。这种分而治之的算法设计思想具有以下几个优点:
动态规划
动态规划(Dynamic Programming)是另一种广泛应用的算法设计方法,它与分而治之有一些共同之处,但也有一些重要的区别
动态规划的核心思想是:
- 问题的拆解:将一个大问题拆解成多个相互关联的子问题。子问题之间存在重叠的部分,即同一个子问题可能会被多次用到
- 自底向上的求解:从最小的子问题开始,逐步求解出较大的子问题。最终得到原问题的解决方案
- 存储中间结果:为了避免重复计算,动态规划会将已经计算过的中间结果存储起来,以备后用。这种方法称为"记忆化"(Memoization)
与分而治之不同的是,动态规划算法通常会利用子问题之间的依赖关系,并根据这种依赖关系构建一个递推的解决方案。这种方法通常可以得到一个更加高效的算法,但需要更多的空间来存储中间结果
与分而治之相比,动态规划算法更适用于那些存在重叠子问题的复杂问题,因为它可以避免重复计算,从而提高算法的效率。但同时,动态规划也需要更多的空间来存储中间结果
贪心
贪心算法(Greedy Algorithm)是另一种常见的算法设计方法,它与分而治之和动态规划有一些共同点,但也有一些明显的区别
贪心算法的核心思想是:
- 局部最优:在每一步操作中,都选择当前看起来最好的选择,即局部最优解。这样做的目标是最终得到全局最优解
- 无后效性:贪心算法做出的每一个选择都不依赖于未来的选择,只依赖于当前状态和局部最优解。换句话说,贪心算法不会"回头"去修改之前的选择
- 贪心策略:贪心算法通常会根据问题的特点,设计出一种贪心策略。这种策略会指导如何在每一步做出最优的局部选择
与分而治之和动态规划不同的是,贪心算法不会将问题分解成子问题,也不会存储中间结果。它会直接根据贪心策略做出选择,并最终得到一个解决方案
回溯
回溯算法(Backtracking)是另一种常见的算法设计方法,它与分而治之、动态规划和贪心算法有一些共同特点,但也有一些独特的地方
回溯算法的核心思想是:
- 探索所有可能性:回溯算法通过系统地枚举所有可能的候选解,来寻找满足问题陈述的解。它会不断尝试各种可能的解决方案,直到找到一个可行的解
- 试错回溯:如果当前的选择导致了问题,回溯算法会"回溯"到之前的某个选择点,并尝试其他的选择 这种试错和回溯的过程一直持续,直到找到一个满足要求的解决方案
- 决策树:回溯算法可以用一棵决策树来表示问题的解决过程。每个节点代表一个决策点,分支代表可能的选择,叶节点代表最终的解决方案
与分而治之和动态规划不同,回溯算法并不试图将问题分解成相互独立的子问题,而是通过系统地探索所有可能的解决方案来找到满足要求的解