【前端】整理了十条算法题&方法(简短但精细!)

302 阅读3分钟

前言

在平时的工作和学习中记录了一些算法题和方法,整理了几条出来分享一下。话不多说直接开整。

1.数组去重

let array = [1, 1, 2, 2, 3, 3];
// 1.使用new Set() ES6新增的数据结构,类似于数组,它的特征是所有元素都是唯一的,没有重复的值
// 无法去重引用数据类型
let result1 = [...new Set(array)];

// 2.使用数组的filter和indexOf方法
let result2 = array.filter((item,index) => array.indexOf(item) == index);

// 3.使用数组的reduce和includes实现
let result3 = array.reduce((pre,cur) => {
    if(!pre.includes(cur)){
        pre.push(cur);
    }
    return pre;
},[]);

// 4.双层for循环实现
for(let i = 0; i < array.length; i++){
    for(let j = i + 1; j < array.length; j++){
        if(array[i] == array[j]){
            array.splice(j,1);
            j--
        }
    }
}

2.数组排序

let array = [2, 4, 6, 1, 5, 8, 7, 10, 3];
// 1.使用数组sort方法
let result1 = array.sort((a,b) => a - b);

// 2.双层for循环实现
for(let i = 0; i < array.length; i++){
    for(let j = i; j < array.length; j++){
        if(array[i] > array[j]){
        let temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

3.经典题-两数之和

let array = [172, 82, 46, 24, 32];
// 1.双层for循环暴力解法
let twoSum = function(arr, target){
    for(let i = 0; i < arr.length; i++){
        for(let j = i + 1; j < arr.length; j++){
            if(arr[i] + arr[j] == target){
                return [i, j]
            }
        }
    }
}
twoSum(array,106); // => [1, 3]
// 2.利用map解,降低时间复杂度
let twoSumMap = function(arr, target){
    const map = new Map();
    for(let i = 0; i < arr.length; i++){
        if(map.has(target - arr[i])){
            return [map.get(target - arr[i]), i]
        }
        map.set(arr[i], i)
    }
    return [];
}
twoSumMap([172, 82, 46, 24, 32], 78); // => [2, 4];

4.两个数组的交集

let intersect = function(num1, num2){
    let map1 = makeCountMap(num1);
    let map2 = makeCountMap(num2);
    let res = [];
    
    for(let num of map1.keys()){
        let count1 = map1.get(num);
        let count2 = map2.get(num);
        
        if(count2){
            let pushCount = Math.min(count1, count2);
            for(let i = 0; i < pushCount; i++){
                res.push(num);
            }
        }
    }
    return res;
}

function makeCountMap(nums){
    let map = new Map();
    for(let i = 0; i < nums.length; i++){
        let num = nums[i];
        let count = map.get(num);
        if(count){
            map.set(num, count + 1);
        } else {
            map.set(num, 1)
        }
    }
    return map;
}
intersect([15, 20, 35, 10], [3, 8, 10, 15]) // => [15, 10]

5.数组扁平化

let arrays = [[1, 2], [3, 4], [5, 6]];
// 1.使用数组flat方法传入Infinity 展开任意深度的嵌套数组
let result1 = arrays.flat(Infinity);

// 2.使用toString转字符串
let result2 = arrays.toString().split(',').map(item => item);

// 3.使用reduce
let flatten = function(arr){
    return arr.reduce((pre, cur) => {
        return pre.concat(Array.isArray(cur) ? flatten(cur) : cur)
    },[])
}

6.斐波那契数列

// 从第三项开始 当前项的值是前两项值的和
// 写法1
function fib1(n){
    if(n < 2) return 1;
    let dp = [1, 1];
    for(let i = 2; i <= n; i++){
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    return dp[n]
}
// 写法2
function fib2(n){
    if(n < 2) return 1;
    return fib2(n - 1) + fib2(n -2);
}
// 写法3
let fib3 = function(num, num1 = 1, num2 = 1){
    return num <= 1 ? num2 : fib3(num - 1, num2, num1 + num2)
}
// 写法4
let fib4 = function(num){
    return num <= 1 ? 1 : fib4(num - 1) + fib4(num - 2);
}
fib1(10) => 89

7.将rgb转为HEX - 将HEX转rgb

// 1.rgb转HEX
let rgbToHex = (r, g, b) => {
    let toHex = (num) => {
        let hex = num.toString(16);
        return hex.length === 1 ? `0${hex}` : hex;
    }
    return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}
rgbToHex(46,32,67) // => #2e2043

// 2.HEX转rgb
let hexToRgb = (val, opa) => {
    let pattern = /^(#?)[a-fA-F0-9]{6}$/; // 16进制颜色值校验规则
    let isOpa = typeof opa == 'number' // 判断是否是有设置不透明度
    if(!pattern.test(val)) { return '' }; // 如果值不符合规则返回空字符
    let v = val.replace(/#/, '');
    let rgbArr = [];
    let rgbStr = '';
    for(let i = 0; i < 3; i++){
        let item = v.substring(i * 2, i * 2 + 2);
        let num = parseInt(item, 16);
        rgbArr.push(num);
    }
    rgbStr = rgbArr.join();
    rgbStr = rgbStr = `rgb${isOpa ? 'a' : ''}(${rgbStr + (isOpa ? ',' + opa : '')})`
    return rgbStr;
}
hexToRgb('#2e2043',10) // => rgba(46, 32, 67, 10)

8.判断是否是回文字符串

// 方法1
function isPlalindrome(input){
    if(typeof input !== 'string') return false;
    return input.split('').reverse().join('') === input;
}
isPlalindrome('nexen') // => true
// 方法2
function isPlalindromes(input){
    if(typeof input !== 'string') return false;
    let i = 0; j = input.length - 1;
    while(i < j){
        if(input.charAt(i) !== input.charAt(j)) return false;
        i++;
        j--;
    }
    return true;
}
isPlalindromes('level') // => true
// charAt()方法返回指定索引位置的char

9.关于日期的几个方法

// 1.检查日期是否有效
const isDateValid = (...val) => !Number.isNaN(new Date(...val).valueOf());
isDateValid("December 17, 1995 03:24:00"); // true

// 2.计算两个日期之间的间隔
const dayDif = (date1, date2) => Math.ceil(Math.abs(date1.getTime() - date2.getTime()) / 8
6400000)
dayDif(new Date("2021-11-3"), new Date("2022-2-1")) // => 90

// 3.查找日期位于一年中的第几天
const dayOfYear = (date) => Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 /60 / 24);
dayOfYear(new Date('2022-10-12')); // => 285

// 4.验证一个日期是不是今天
const isToday = function(val){ 
    return new Date().toLocaleDateString() == new Date(val).toLocaleDateString();
}
isToday(new Date()) // => true

10.负数取整问题

const multiplication = function(n1, n2){
    let m = 0;
    let s1 = n1.toString();
    let s2 = n2.toString();
    try {
        m += s1.split(".")[1].length;
    } catch (e) {}
    try {
        m += s2.split(".")[1].length;
    } catch (e) {}
    return (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) / Math.pow(10, m)
}
multiplication(-1.15,100) // => -115
parseInt(-1.15 * 100) // => -114

完结

如果有帮助到你,请点个赞哦,感谢。