前端算法整理
深度遍历树
const data = [
{
name: 'a',
children: [
{ name: 'b', children: [{ name: 'e' }] },
{ name: 'c', children: [{ name: 'f' }] },
{ name: 'd', children: [{ name: 'g' }] },
],
},
{
name: 'a2',
children: [
{ name: 'b2', children: [{ name: 'e2' }] },
{ name: 'c2', children: [{ name: 'f2' }] },
{ name: 'd2', children: [{ name: 'g2' }] },
],
}
]
// 深度遍历, 使用递归
function getName(data) {
const result = []
data.forEach(ele =>{
// 定义递归函数
const deep = item =>{
result.push(item.name)
// 如果有还是,调用递归
item.children && item.children.forEach(child => deep(child))
}
deep(ele)
})
return result.join(',')
}
console.log(getName(data))
广度遍历树
const data = [
{
name: 'a',
children: [
{ name: 'b', children: [{ name: 'e' }] },
{ name: 'c', children: [{ name: 'f' }] },
{ name: 'd', children: [{ name: 'g' }] },
],
},
{
name: 'a2',
children: [
{ name: 'b2', children: [{ name: 'e2' }] },
{ name: 'c2', children: [{ name: 'f2' }] },
{ name: 'd2', children: [{ name: 'g2' }] },
],
}
]
function getName2(data) {
const result = []
// 数组不为空择一直重复进入循环
while(data.length>0){
[...data].forEach(ele => {
data.shift()
result.push(ele.name)
ele.children && data.push(...ele.children)
})
}
return result.join(',')
}
console.log(getName2(data))
实现一个函数,输入一个字符串,返回该字符串出现最多的字母
输入示例 AABABABFCFFFFFDF
输出示例 F
const str1 = 'AABABABFCFFFFFDF'
function getMostStr(str){
// 定义存储出现次数最多的变量
let mostStr=''
// 定义存储每个字符出现次数的对象
const numRate = str.split('').reduce(function(pre, cur){
pre[cur] ? pre[cur] ++ : pre[cur] = 1
return pre
},{})
// 将字符出现次数最多的字符赋值给mostStr
Object.keys(numRate).forEach(ele =>{
if(!mostStr){
mostStr = ele
}else{
if(numRate[mostStr]<numRate[ele]) mostStr = ele
}
})
return mostStr
}
console.log(getMostStr(str1));
编写查询函数返回数字字符串中最大的公共前缀字符串
输入示例[flower,flow,flight]
输出示例 fl
const arr1 = ['flower','flow','flight']
function getPrefix(arr){
let result = arr[0]
// 循环获取最小字符串
arr.map(ele =>{
if(ele.length<result.length) result = ele
})
// 循环依次对比最小字符串是否包含与当前字符串,如果没有,最小字符串从后面删除一位
for(let i = 0;i<arr.length;i++){
if(arr[i].indexOf(result) === -1){
result = result.slice(0,result.length-2)
i--
}
}
return result
}
console.log(getPrefix(arr1))
计算派出机器人的数量
有一个大型仓库使用拣货机器人从不同的货架间取货。
已知:
1、货架呈二维网格排列,网格中的每个货架只会放置一种商品。
2、受这代设备的技术水平所限,机器人只能沿上下左右四个方向移动,还不能沿斜线移动,请理解。
仓库当前使用的拣货算法是这样:
1、一张订单会包含X种商品,分布在X个货架上
2、结合将这X种商品的所在位置,将地图上的商品分解为Y个“商品堆”,然后同时派出Y个机器人,并发取货,每个机器人只负责一个“商品堆”。
3、“商品堆”的定义是上下左右彼此相邻的一组商品。
在订单被分析后,给你一个由 ‘1’(该货架有待取货物)和 ‘0’(该货架没有待取货物)组成的的二维网格表示货架地图,请计算需要派出的机器人的数量。
输入示例 [[1,1,1,1,0],[1,1,0,1,0],[1,1,0,0,0],[0,0,1,0,1]]
输出示例 3
const goodsArr = [[1,1,1,1,0],[1,1,0,1,0],[1,1,0,0,0],[0,0,1,0,1]]
function getRobot(arr){
let robotNum = 0
// 每行货物个数
const row = arr[0].length
// 每列货物个数
const column = arr.length
// 循环判断是否有货物
arr.forEach((item,colInd)=>{
item.forEach((ele,rowInd)=>{
if(ele === 1){
robotNum++
RobotWork(colInd,rowInd)
}
})
})
// 派出机器人分拣货物
function RobotWork(curCol,curRow){
arr[curCol][curRow] = 0
if(curCol+1 < column && arr[curCol+1][curRow] === 1) RobotWork(curCol+1,curRow)
if(curRow+1 < row && arr[curCol][curRow+1] === 1) RobotWork(curCol,curRow+1)
if(curCol > 0 && arr[curCol-1][curRow] === 1) RobotWork(curCol-1,curRow)
if(curRow > 0 && arr[curCol][curRow-1] === 1) RobotWork(curCol,curRow-1)
}
return robotNum
}
console.log(getRobot(goodsArr));
计算200以内正整数的阶乘
输入示例 10
输出示例 3628800
function factorial(num){
if(num < 1 || num > 200) return 'Error'
function deep(n){
if(n === 1) return 1
return n * deep(n-1)
}
return deep(num)
}
console.log(factorial(10));
计算最大路径
输入示例 [ [2,2,1], [2,5,3], [4,2,1] ]
输出示例 13
const pathArr = [ [1,2,3,1],[4,5,6,1],[7,8,9,1] ]
function maxPath(arr){
// 定义所走距离
let pathNum = arr[0][0]
// 获取最行
const row = arr[0].length
// 获取最列
const column = arr.length
// 定义是否循环
let loop = true
// 当前行
let curRow = 0
// 当前列
let curCol = 0
while (loop){
// 判断是否走到了最大行或列
if(curRow+1 === row || curCol+1 === column) {
// 判断是否走到终点
if(curRow+1 === row && curCol+1 === column){
loop = false
return pathNum
}else if(curRow+1 === row) {
nextPath(arr[curCol+1][curRow])
curCol++
} else {
nextPath(arr[curCol][curRow+1])
curRow++
}
}else{
if(arr[curCol+1][curRow] > arr[curCol][curRow+1]){
nextPath(arr[curCol+1][curRow])
curCol++
}else{
nextPath(arr[curCol][curRow+1])
curRow++
}
}
}
function nextPath(path){
pathNum += path
}
}
console.log(maxPath(pathArr));
快速排序
function quickSort(arr){
if(arr.length <= 1 ) return arr
const left = [], right = [], current=arr.splice(0,1)
arr.map(ele =>{
if(ele < current){
// 小于参考值放左边
left.push(ele)
}else{
// 否则放右边
right.push(ele)
}
})
return quickSort(left).concat(current,quickSort(right))
}
console.log(quickSort([3,44,15,36,26,27,2,46,4,19,50,48]))
插入排序
function insertSort(arr) {
arr.forEach((ele, ind) => {
for( let i = ind ;i>=0;i--){
if(arr[i-1]>ele){
arr[i] = arr[i-1]
}else{
arr[i]=ele
break
}
}
})
return arr
}
console.log(insertSort([3,44,15,36,26,27,2,46,4,19,50,48]))
剩余数乘积
返回数组的每一项的值是输入数组除去对应项之外其他项的乘积
输入示例 [ 1,2,3,4 ]
输出示例 [24,12,8,6]
function residualProduct(arr){
const result = []
arr.forEach((ele,ind) => {
let curResult = 1
arr.forEach((item,itemInd) => {
if(itemInd !== ind) curResult = curResult * item
})
result.push(curResult)
})
return result
}
console.log(residualProduct([1,2,3,4]));
递减选择
返回数组的递减子数组
输入示例[4,3,5,1,2,5]
输出示例 [[4, 3, 1],[5, 2],[5,]]
console.log(subDesc([4,3,5,1,2,5]));
function subDesc(arr){
const result = []
arr.forEach(ele=>{
if(result.length === 0){
result.push([ele])
}else{
for(let i = 0; i< result.length; i++){
if(result[i][result[i].length-1] > ele){
result[i].push(ele)
break
}else if(i === result.length-1){
result.push([ele])
break
}
}
}
})
return result
}
获取最大子串
输入示例 ‘12845’ 2
输出示例 84
function maxStr(str,num){
const resultArr = []
// 截取所有字符串
for(let i = 0; i<str.length-num+1; i++){
resultArr.push(str.substring(i,i+num))
}
let max = resultArr[0]
resultArr.map(ele=>{
if(ele>max) max = ele
})
return max
}
console.log(maxStr('12845',2));