列举一些面试可能会考到但是实际工作中使用频率较低的算法。
1、扁平数组转树形结构
const flatArray = [
{id: 2, parentId: 1, name: 'child1'},
{id: 1, parentId: null, name: 'root1'},
{id: 3, parentId: 1, name: 'child2'},
{id: 4, parentId: 2, name: 'grandchild1'},
{id: 5, parentId: 4, name: 'grandchild2'},
{id: 6, parentId: 5, name: 'grandchild3'},
{id: 7, parentId: null, name: 'grandchild4'},
{id: 8, parentId: 6, name: 'grandchild5'},
];
function arrayToTree(items) {
// 存放结果集
const result = []
// 利用map结构,保存
const map = {}
for (const item of items) {
map[item.id] = {...item}
}
for (const item of Object.values(map)) {
// 因为数组元素子代的parentId === 父元素id,将父元素的id作为key保存到map里面
// 然后通过子元素的parentId来查找对应关系
if (map.hasOwnProperty(item.parentId)) {
// 这里多加的判断是为了在没有子代元素的时候,不出现children属性
if (map[item.parentId].hasOwnProperty('children')) {
map[item.parentId].children.push(item)
} else {
map[item.parentId].children = [item]
}
} else {
// parentId === null的肯定是一级菜单,可以直接在这里进行判断
result.push(item)
}
}
return result
}
console.time('arrayToTree')
const result1 = arrayToTree(flatArray)
console.timeEnd('arrayToTree') // 0.1ms左右
2、树形结构转扁平数组
function treeToArray(tree) {
const flatResult = []
function innerFlat(arr) {
arr.forEach(item => {
const target = {...item}
if (target.children) {
innerFlat(target.children)
delete target.children
}
flatResult.push(target)
})
}
innerFlat(tree)
return flatResult.sort((a, b) => a.id - b.id)
}
3、十进制转任意进制
const charsDict = '0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ-~'
function toAnySystem(chars, number) {
const radix = chars.length // 被转换的进制
let qutient = +number, // 将要被转换的数字
arr = [] //保存结果
let mod
do {
// 对需要被转换的数字进行取余,这个是余数
mod = qutient % radix;
// 这个是商
// 被取余之后这个数字一定可以被64整除,获取到取余之后的商
// 如果这个数字大于64,那么qutient就不等于0,反之为0
// 不等于0需要继续往前敬1,进入下一个循环,否则退出循环
qutient = (qutient - mod) / radix;
arr.unshift(chars[mod]);
} while (qutient);
return arr.join('');
}
const num = 9999
console.log(toAnySystem(charsDict, num)) // '2sf'
4、任意进制转换回十进制
function anyTo10System(num, dict) {
let result = 0
// 将字符串反转,因为二进制的字符串110转换为十进制可以理解成 0*2**0 + 1*2**1 + 1*2**2
// 其它进制同理
const numToArr = num.split('')
let i = 0
while (i < numToArr.length) {
result += dict.indexOf(numToArr[i]) * dict.length ** (numToArr.length - 1 - i)
i++
}
return result
}
const twoSystem = '2sf'
console.log(anyTo10System(twoSystem, charsDict)) // 9999