贪心算法
贪心算法,又名贪婪算法,是算法设计中的一种思想
我们要如何去理解呢,见名知意,既要还要,既要每一个阶段都是局部最优,又要达到全局最优,实际上并不是每一个阶段局部最优最后得到的结果就是最优方案。
举个案例,如下图我画的商品价格与销售关系图,我们希望销售越高越好,价格越高越好,我们期望它们能同时满足,这就叫贪心算法,每一个方面都希望是最优,但是实际上,销量与价格是相互影响的,关联性非常大,因此这类不适用贪心算法。
适用场景
贪心选择:当某一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次做出的选择可以依赖以前做出的选择,但不需要依赖后面需要做出的选择。简而言之就是局部之间互不影响。
最优子结构:如果一个问题的最优解包含其子问题的最优解,则此问题具备最优子结构的性质。问题的最优子结构性质是该问题是否可以用贪心算法求解的关键所在。
适用案例,比如考试成绩,语文,数学与英语并没有强关联,即使数学差也丝毫不影响英语成绩,想要总成绩第一,每一门都第一是最好的选择
回溯算法
回溯算法,也是算法设计中的一种思想,是一种渐进式寻找并构建问题解决方式的策略,本质上是属于穷举
回溯算法会先从一个可能的工作开始解决问题,如果不行,就回溯并选择另一个动作,直到将问题解决。
举个例子,我有一百个杯子,其中99个里面是水,1个是醋,用回溯算法的思想来处理的话,一杯一杯的尝,喝一杯,是水,返回重新开始喝下一杯,直到喝到醋,这个过程才算是结束。
使用回溯算法的问题,有如下特性:
1,有很多路,例如一个矩阵的方向或者树的路径
2,在这些的路里面,有死路也有生路,思路即不符合题目要求的路,生路则符合
3,通常使用递归来模拟所有的路
常见的伪代码如下:
result = []
function backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 of 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
重点解决三个问题:
1,路径:也就是已经做出的选择
2,选择列表
3,结束条件
看起来好像不是很好理解,我举个例子,如图所示,我需要在下面非负数集合中找到和为8的完整路径,从左往右,大于[1,7,8]=16的直接返回,第二条[1,8]路径到第二层是9,已经不可能达到预期目标了,这一条是死路,直接返回。直到找到目标,达成结束条件,整个查找过程结束
回溯算法的景点案例还得是八皇后问题
在 8×8 的国际象棋棋盘上放置八个皇后,使得任意两个皇后都不能处于同一条横行、纵行或斜线上,如下图所示,请问有多少种摆法?
function solveNQueens(n) {
let result = [];
let chessboard = new Array(n).fill(0).map(() => new Array(n).fill('.'));
const isValid = (row, col) => {
for (let i = 0; i < row; i++) {
if (chessboard[i][col] == 'Q') return false;
}
for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (chessboard[i][j] == 'Q') return false;
}
for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
if (chessboard[i][j] == 'Q') return false;
}
return true;
};
const backtrack = (row) => {
if (row == n) {
let queens = chessboard.map(row => row.join('')).join('\n');
result.push(queens);
return;
}
for (let col = 0; col < n; col++) {
if (isValid(row, col)) {
chessboard[row][col] = 'Q';
backtrack(row + 1);
chessboard[row][col] = '.';
}
}
};
backtrack(0);
return result;
}
const n = 8;
console.log(solveNQueens(n));
这段代码定义了一个solveNQueens函数,它接受一个参数n表示棋盘的大小,并返回所有可能的放置解。函数内部定义了一个chessboard数组来表示棋盘,其中用’Q’表示已放置的皇后,用’.'表示空位。isValid函数检查在当前行和列放置一个新的皇后是否安全。backtrack函数是回溯算法的核心,它递归地尝试在每一行放置一个皇后。当放置完所有的皇后后,将当前的棋盘状态添加到结果列表中。
额,没必要去研究,主要还是能理解什么是贪心算法,跟回溯算法即可