1. 回溯法(Back Tracking Method)(探索与回溯法)
回溯法是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为 “回溯点”。
可以把回溯法看成是递归调用的一种特殊形式。
代码方面,回溯算法的框架:
const result = []
function backtrack(路径, 选择列表){
if (满足结束条件){
result.add(路径)
return
}
for( 选择 in 选择列表){
做选择
backtrack(路径, 选择列表)
撤销选择
}
}
2.二分法
在数组nums中查找target的下标
var searchInsert = function(nums, target) {
let left = 0, right = nums.length - 1, middle = 0
while(left <= right){
middle = parseInt((left+right)/2)
if (nums[middle] > target) {
right = middle - 1; //target在左区间,所以[left, middle - 1]
} else if (nums[middle] < target) {
left = middle + 1; //target在右区间,所以[middle + 1, right]
} else { //既不在左边,也不在右边,那就是找到答案了
return middle;
}
}
};
3.约瑟夫环——公式法(递推公式)
约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报。如此反复,最后剩下一个,求最后的胜利者。
原文链接:https://blog.csdn.net/u011500062/article/details/72855826
递推公式:
f ( N , M ) = ( f ( N − 1 , M ) + M ) % N
f(N,M)表示,N个人报数,每报到M时杀掉那个人,最终胜利者的编号
f ( N − 1 , M ) 表示,N-1个人报数,每报到M时杀掉那个人,最终胜利者的编号
function cir(n, m)
{
let p=0;
for(let i = 2;i <= n; i++)
{
p=(p+m)%i;
}
return p+1; // 因为p的结果是数组的下标,所以结果还需要+1
}
个人理解主要就是:当最后只剩一个a的时候a必然是胜利者,a的下标是0,那么这时候往回推,剩两个人的时候a的下标是多少呢?剩三个人的时候a的下标是什么呢?一直寻找到最开始的时候a的下标,这时候a的下标就是我们要的答案!