简单算法
- 字符串
- 数组
- 正则
- 排序
- 递归
算法修炼什么?
- 思维
- 专注
- 视野
- 技巧
如何修炼算法?
理论知识 + 大量练习
- 《算法导论》,《概率》
- 组内分享 + 引导 + 实战
星级
数组展平简单 (零星)
展平一个数组,数组最多二维 [[1, 2], [3, 4]]
=> [1,2,,3,4]
arr = [[1, 2], [3, 4]]
[].concat([[1, 2], [3, 4]])
[].concat(...[[1, 2], [3, 4]])
[].apply(null, [[1, 2], [3, 4]])
function flattenOnce(arr) {
return [].concat(...arr)
}
数组展平(递归,一星)
展平一个数组,[[1, 2], 3, [[4], 5]]
=> [1, 2, 3, 4, 5]
对数组S={a1, a2, ... an}
, 函数F将数组展平。
function flatten(arr) {
return [].concat(...arr.map(x => {
Array.isArray(x) ? flatten(x) : x
}))
}
函数截流 (一星)
过滤掉重复掉滚动事件
时序图:
function throttle(func, delay = 60) {
let lock = false
return (...args) => {
if (lock) return
func(...args)
lock = true
setTimeout(() => {lock = false}, delay)
}
}
调用:
throttle(console.log)
函数节流 (一星)
过滤掉重复的验证事件(用户输入停止后300ms触发验证)
function throlle(func, delay = 300, I = null) {
return (...args) => {
clearInterval(I)
I = setTimeout((...args) => func(...args), delay)
}
}
柯里化 (二星)
对于curry(foo)
, g
函数参数足够4个,就调用foo(a, b, c, d),如果小于4个就返回一个可继续积累参数的函数
const curr = func => {
const g = (...allArgs) => allArgs.length >= func.length ? func(...allArgs) : (...arg) => g(...allArgs, ...args)
return g
}
调用:
const = foo = curry((a, b, c, d) => {
console.log(a, b, c, d)
})
foo(1)(2)(3)(4) // 1 2 3 4
foo(1)(2)(3) // 不返回
const f = foo(1)(2)(3)
f(5) // 1 2 3 5
Y-组合子(三星)
在上述柯里化函数中去掉const g
?
前置lambda
演算。
const y = functon (le) {
return function (f) {
return f(f)
}(function (f) {
return le(
function (...x) {
return (f(f)(...x))
}
)
})
}
const curryY = func => y(
g => {
(...allArgs) => {
allArgs.length >= func.length ? func(...allArgs) : (...args) => g(...allArgs, ...args)
}
}
)
const foo = curryY((a, b, c, d) => {
console.log(a, b, c, d)
})
foo(1)(2)(3)(4)
树的编辑距离(DOM-DIFF) (四星)
将DOM抽象成一颗标签树
DOM-DIFF算法可以抽象成标签树的编辑距离
数学函数Math
- 分页操作
- 数组最值
- 随机数生成
- 素数判断
重要的Math
函数
Math.abs 求绝对值
Math.ceil 向上取整
Math.floor 向下取整
Math.max 求最大数
Math.random 0~1之间的随机数
Math.sqrt 平方根
Math.sign 求数值的符号
Math.pow 求幂
分页计算:
在一个分页表格中,给定每页显示条数(pageSize)和元素的序号(index)求页码。
const pageNo = Math.ceil((index + 1) / pageSize)
pageSize = 10
0 -> 1
9 -> 1
10 -> 2
11 -> 2
数组最值:
const A = [1, 2, 4, 5, 6]
const max = Math.max(...A)
// const max = Math.max.apply(null, A)
// const max = Math.max(1, 2, 4, 5, 6)
生成20-30之间的随机整数:
Math.round(20 + Math.random() * 10)
判断一个数是否是素数:
function is_prime(n) {
if (n <= 1) return false
const N = Math.floor(Math.sqrt(n)) // 除平方根
let is_prime = true
for (let i = 2; i <= N; i++) {
if (n % i === 0) {
is_prime = false
break
}
}
return is_prime
}
数组和链式操作
- JS原生的数组操作
- 扩展库
- 算法举例:括号匹配,子数组整除
- SQL对应的数据处理
迭代器和GeneratorRamda
- zip
- converge
- innerJoin
- flatten
- intersperse
leetcode
反转字符串
例如:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
思路:
- 字符串按空格进行分割,保存数组,利用数组的反转,数组的元素的先后顺序就是单词的顺序。
- 对数组进行遍历,然后每个元素进行反转。
code:
let reverseString = function(s) {
return s.split(' ').map(item => {
return item.split('').reverse().join('')
}).join('')
};
let reverseString = function(s) {
return s.match(/[\w']+/g).map(item => {
return item.split('').reverse().join('')
}).join('')
};
计算二进制子串
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。