你可能不知道的前端算法

89 阅读3分钟

1、 判断数字x是否是2的n次方,x>0且为整数

/**
 * 判断数字x是否是2的n次方,x>0且为整数
 */
// 方法一(while循环反复除)
function isPowerOf2(x) {
  if (x < 1) {
    return false
  }
  while (x >= 2) {
    x = x / 2
    if (x - 1 === 0) {
      return true
    }
  }
  return false
}

// 方法二(while循环反复乘)
function isPowerOf2(x) {
  let flag = 1
  while (flag) {
    if (flag < x) {
      flag = flag * 2
    } else if (flag === x) {
      return true
    } else {
      return false
    }
  }
}

// 方法三(且运算)
function isPowerOf2(x) {
  return (x & (x - 1)) === 0
}
/*
& 对操作数的二进制数中对应的每一位都做与运算,如果对应位都为1则结果为1,如果对应位有一个是0,则结果为0
1 的二进制表示为: 00000000 00000000 00000000 00000001
3 的二进制表示为: 00000000 00000000 00000000 00000011 
console.log(1 & 3) // 1
*/

2、 一个数组中包含了一个或多个正整数,其他数字都出现了2次,只有一个数字出现了1次,找出只出现一次的数字

/**
 * 一个数组中包含了一个或多个正整数,其他数字都出现了2次,只有一个数字出现了1次,找出只出现一次的数字
 */
// 方法一(forEach遍历,indexOf和lastIndexOf对比)
function uniqueNumber(nums) {
  let result = 0
  nums.forEach(item => {
    const firstIndex = nums.indexOf(item)
    const lastIndex = nums.lastIndexOf(item)
    if (firstIndex === lastIndex) {
      result = item
    }
  })
  return result
}

// 方法二(reduce遍历计算每个数字出现的次数)
function uniqueNumber(nums) {
  let result = 0
  const obj = nums.reduce((a, b) => {
    if (b in a) {
      a[b]++
    } else {
      a[b] = 1
    }
    return a
  }, {})
  Object.keys(obj).forEach(key => {
    if (obj[key] === 1) {
      result = key
    }
  })
  return result
}

// 方法三(异或运算)
function uniqueNumber(nums) {
  return nums.reduce((a, b) => a ^ b, 0)
}
/*
设a=1,b=3, 那么a=0001,b=0011, a^b=0001^0011=0010, a^b^a=a^a^b=0001^0001^0011=0000^0011=0011
当两个数做异或运算的时候对应的位置,如果相同则为0,不同则为1
异或运算的特性:
1:一个数异或自己时等于0;
2:一个数异或0的时候,结果是其本身
3: 异或运算具有交换律,a^b^c^a^c=a^a^c^c^b
*/

3、将数字(如:100000000)转为如下格式的字符串(100,000,000)

/**
 * 将数字(如:100000000)转为如下格式的字符串(100,000,000)
 */
// 方法一(toLocaleString)
function convertNumber(num) {
  return num.toLocaleString()
}

// 方法二(正则)
function convertNumber(num) {
  return num.toString().replace(/(?=\B(\d{3})+$)/g, ',')
}

4、验证回文串

image.png

/**
 * 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写
 */
// 方法一(先将字符串倒转再比较)
function isPalindrome(s) {
  let str = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()
  let str2 = str.split('').reverse().join('')
  return str === str2
}

// 方法二(双指针前后判断)
function isPalindrome(s) {
  let str = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()
  let left = 0
  let right = str.length - 1
  while (left < right) {
    if (str[left] === str[right]) {
      left++
      right--
    } else {
      return false
    }
  }
  return true
}