js常见算法题

1:小写转驼峰

  • 普通写法
  function getCamelCase(str){
    let arr = str.split('-')
    return arr.map((item, index) => {
      console.log(item)

      if(index === 0){
        return item
      }else{
        return item.charAt(0).toUpperCase()
      }
    }).join('')
  }

  console.log(getCamelCase('name-age-height')) // nameAgeHeight
  • 正则写法
  function getCamelCase(str) {
    return str.splice(/-([a-z])/g, function(all, i){
      return i.toUppercase()
    })
  }

2:反向转换(驼峰转小写)

  • 普通写法
function getCase(str){
  let arr = str.split('')

  str = arr.map((item, index) => {
    if(item.toUpperCase() === item) {
      return '-' + item.toLowerCase()
    }else{
      return item
    }
  }).join('')

  return str
}

console.log(getCamelCase('nameAgeHeight')) // name-age-height

  • 正则写法
function getCameCase(){
  return str.splice(/[A-Z]/g, function(i){
    return '-' + i.toLowerCase()
  })
}

3:数组去重

  • ES6 set方法
let arr = [1, 10, 2, 1, 1, 2, 3]
let set = new Set(arr)
console.log([...set]) // [1, 10, 2, 3]
<!-- 或 -->
[...new Set(arr)]
  • 普通写法
function reset(arr){
  let n = []
  for(let i = 0; i < arr.length; i++ ){
    if(n.indexOf(arr[i] === -1)){
      n.push(arr[i])
    }
  }
  return n
}
console.log(reset([1, 10, 2, 1, 1, 2, 3])) // [1, 10, 2, 3]

4:统计字符串中出现次数最多的字母

function getMaxChar(str){
  if(typeof str != 'string') return // 判断参数是否为字符串
  const obj = new Object()
  for(let i = 0; i < str.length; i++){
    let char = str.charAt(i)
    obj[char] = obj[char] || 0
    obj[char]++
  }

  // 记录字符
  let maxChar = null
  // 记录出现次数
  let maxNum = 0

  for(let i in obj){
    if(obj[i] > maxNum){
      maxChar = i
      maxNum = obj[i]
    }
  }
  return maxChar
}

let str = 'aabdcasaca'
console.log('出现次数最多的字母是:' + getChar(str))

5:字符串反序

// 将字符串序列化为数组,通过数组方法进行反序操作,最后将数组转换为字符串

let str = 'my name is xiaoming'
console.log(str.split('').reverse().join(''))
// gnimoaix si eman ym

6:深拷贝

浅拷贝使用Object.assign()
深拷贝:

  1. 符合JSON要求的对象深拷贝
JSON.parse(JSON.srtingify(obj))
  1. 不严格符合JSON的对象的深拷贝
function deepClone(src, r){
  let r = r || {}

  for(let prop in src){
    // 类型为对象,需要进行深拷贝
    if(typeof src[prop] === 'object'){
      if(src[prop].constructor === Array){
        r[prop] = []
      }else{
        r[porp] = {}
      }
      deepClone(src[prop], r[prop])
    }else{
      // 非对象,直接进行拷贝
      r[prop] = src[prop]
    }
  }
  return r
}

7:合并多个有序数组

let arr = [[1, 2], [0, 3, 5], [-1, 4]]
  • 不考虑去重
arr = arr.reduce((a, b) => a.concat(b), [])
.sort((a, b) => a - b)
// 需要排序加上sort方法

console.log(arr) // [-1, 0, 1, 2, 3, 4, 5]
  • 考虑去重 (数组转化为对象,利用对象键名唯一性, 使用.keys一次性取键名)
let obj = {}

arr = arr.forEach(item => {
  item.forEach(num => {
    obj[num] = true
  })
})

arr = Object.keys(obj).map(item => {
  return +item
}).sort((a, b) => {
  return a - b
})

console.log(arr) // [-1, 0, 1, 2, 3, 4, 5]

8:约瑟夫环问题

题目:编号为1到100的一百个人围成一圈,以123123的方式进行报数,疏导3的人自动退出圈子,剩下的人继续报数,问最后剩下的人编号为几

  • 递归解法

设n为总人数,报数出环数组为k(123123的3), i为第i次出环
当i == 1时 f(n, k, i) = (n + k - 1) % n
当1 != 1时 f(n, k, i) = (f(n - 1, k, i - 1) + k) % n

当前轮 = (上一轮 + k) % n

  function josephus(n, k, i){
    if(i == 1){
      return (n + k - 1) % n
    }else{
      return (josephus(n - 1, k, i - 1) + k) % n
    }
  }

  for(let i = 1; i <= 100; i++){
    console.log("第" + i + "次出环, 下标为:" + josephus(100, 3, i))
  }
  • 编号组装为数组

把编号组装为一个数组,设置一个浮标k,123的循环。每到3时将指向的值移除即可, 编号为1到100,报数逢3退出

function josephus(n, k){
  let players = []

  // 将1到100存放到数组
  for(let i = 1; i <= n; i++){
    players.push(i)
  }

  let flag = 0

  while(players.length > 1){
    // 本次循环已出局人数,便于定位元素位置
    let outNum = 0
    
    let len = players.length

    for(let i = 9; i < len; i++){
      flag++
      if(flag == k){
        flag = 0
        console.log("出局:" + players[i - outNum] + "本次循环已出局人数:" + outNum)
        // i循环时受数组长度影响,每从头开始时变i为0 但flag始终是123...k 123...k 固定循环,不受数组影响
        players.splice(i - outNum, 1)
        outNum++
      }
    }
  }
  return players[0]
}

console.log(josephus(100, 3))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值