查找算法常用的顺序查找与二分查找,算法思想动态规划、贪心算法、回溯算法……
一 查找算法
查找,根据给定的某个值,在给定的表中确定一个等于给定值的数据元素或记录。
1. 顺序查找
顺序查找,遍历数据元素,直到找到对应的元素,找不到,返回 -1。适合于存储结构为顺序存储或链接存储的线性表,实用于无序和有序数组。
function search (arr, value) {
for(let i = 0,len = arr.length; i < len; i ++) {
if (arr[i] === value) {
return i;
}
}
}
search([12, 4, 3, 2, 5, 84, 34, 52, 42, 45, 6, 7, 86, 68, 67], 2) // 返回索引 3
2. 二分查找
二分查找, 在有序数组中不断取中间值,直到找到对应的元素,找不到,返回 -1。只针对有序数组实用。
const arr = [2, 3, 4, 5, 6, 7, 12, 34, 42, 45, 52, 67, 68, 84, 86];
function binarySearch (arr, value) {
if (arr.length <= 0) {
return -1;
}
let start = 0;
let end = arr.length - 1;
while(start <= end) {
// 不停的取中间值
let mid = Math.floor((start + end) / 2);
// 找到元素后,返回索引
if (value === arr[mid]) {
return mid;
}else if (value < arr[mid]) {
// 当前值 大于 要查找的值
end = mid - 1;
} else if (value > arr[mid]) {
// 当前值 小于 要查找的值
start = mid + 1;
}
}
// 找不到,返回-1
return -1;
}
console.log(binarySearch([2, 3, 4, 5, 6, 7, 12, 34, 42, 45, 52, 67, 68, 84, 86], 4));
二 动态规划
动态规划,为运筹学的一个分支,意为通过将大问题分解为小问题求最优解,从而得到大问题的结论。
动态规划并不是一种特殊算法,而是对解最优化问题的一种途径、一种方法。并没有一种标准的数学表达式和明确的解题方法,由于各种问题性质不同,确定最优解的条件也不相同,不存在一种万能的动态规划算法。
能采用动态规划求解的问题的一般要具有3个性质:
-
最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。
-
无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。
-
有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)
示例:
如上图,用动态规划解决问题如下:
(1) 登上第一台阶:只有一个方法
- 1
(2) 登上第二台阶:有两种方法
- 1 - 1
- 2
(3) 登上第三台阶:有三种方法
- 1 - 1 - 1
- 1 - 2
- 2 - 1
(4) 登上第四台阶:有五种方法
- 1 - 1 - 1 - 1
- 1 - 1 - 2
- 1 - 2 - 1
- 2 - 1 - 1
- 2 - 2
依次类推……
// 爬楼梯方法 ---- 递归版本
function climbStairs (n) {
// 如果当前是 第 0,1,2 层,直接返回n
if (n === 0 || n === 1 || n === 2) {
return n;
}
return climbStairs(n - 1) + climbStairs(n - 2);
}
// 爬楼梯方法 ---- 循环方法
function climbStairs2 (n) {
if (n === 0 || n === 1 || n === 2) {
return n
}
let a = 1; // 当前层的前两层
let b = 2; // 当前层的前一层
let result = 0;
for(let i = 3;i <= n;i ++) {
result = a + b;
a = b;
b = result;
}
return result;
}
参考:yancy__ 、zw6161080123