前端常见算法题

1,741 阅读2分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

前言

这篇文章主要是用来整理前端面试中常碰到的一些算法题,贴的解法是记录我自己的写法,也方便我自己查看。别的更好的写法可以直接从链接到leetcode查看题解。

题目

1. 爬楼梯

爬楼梯时每次可以选择爬1个或2个台阶,问有多少种爬楼梯的方法??

可以看出到达第n个台阶的方法可以通过第n-1个台阶或第n-2个台阶。所以得出:fn(n) = fn(n-1) + fn(n-2)

var climbStairs = function(n) {
    let fn={};
    fn[1]=1;
    fn[2]=2;

    for(let i=3; i<=n; i++) {
        fn[i]=fn[i-1]+fn[i-2];
    }
    return fn[n];
};

具体题解以及其他解决方法可以看leetcode#70

2. 有效的括号

判断括号是否正确闭合??主要包括(),{},[]三种括号。

可以考虑使用栈来实现。遇到左括号进栈,遇到右括号时判断栈顶是否匹配,若匹配则出栈,不匹配则直接返回false

var isValid = function (s) {
    if (s.length % 2) {
        return false;
    }
    let arr = []
    let obj = {
        '(': ')',
        '{': '}',
        '[': ']'
    }
    for(let i=0; i<s.length; i++) {
        if(s[i] in obj) {
            arr.push(s[i]);
        }else {
            let ele = arr.pop();
            if(obj[ele] !== s[i]) {
                return false;
            }
        }
    }
    if(arr.length === 0) {
        return true;
    }
    return false;
};

具体题解以及其他解决方法查看leetcode#20

3. 整数转化英文表示

这个题目虽然在leetcode上被标记为困难,但是本身是一道简单题,只要找对转化规则就好。数字特殊的几种英文表示方式考虑到就不难了。


let oneMap = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"];
let teenMap = ["Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"];
let tenMap = [ "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
let threeDigits = ["Thousand", "Million", "Billion"];


var numberToWords = function(num) {
    if(num === 0) {
        return 'Zero';
    }
    if(num < 10) {
        return oneMap[num];
    }else if(num < 20) {
        return teenMap[num%10];
    }else if(num < 100) {
        let tensDigit = parseInt(num/10);
        let unitsDigit = num%10;
        if(unitsDigit) {  //空格处理
            return tenMap[tensDigit-2] + ' ' +  oneMap[unitsDigit];
        }else {
            return tenMap[tensDigit-2]
        }

    }else if(num < 1000) {
        let hundredDigit = parseInt(num/100);
        if(num%100) {
            return oneMap[hundredDigit] + ' Hundred ' + numberToWords(num%100);
        }else {
            return oneMap[hundredDigit] + ' Hundred';
        }

    }else {
        //三位分割,最大是4294967296,十位数
        let str = '';
        for(let i=3, unit = 1000000000; i>=0; unit/=1000, i--) {
            let digit = parseInt(num/unit);
            if(digit) {
                num -= digit*unit;
                if(str) {
                    str += ' ';
                }
                str += numberToWords(digit);

                if(i>0) {
                    str += ' ' + threeDigits[i-1];
                }
            }
        }

        if(num) {
            return str += ' ' +numberToWords(num);
        }else{
            return str;
        }
    }
};

// console.log(numberToWords(1000000000))
// console.log(numberToWords(20))

具体题解以及其他解决方法可查看leetcode#273

4. 无重复字符的最长子串

这道题第一感觉应该是滑动窗口的解法。但是对于字符串来说无需专门去标记start和end,本身有专门的方法来截取子串。

var lengthOfLongestSubstring = function(s) {
    let len = s.length;
    if(len === 0){
        return 0;
    }
    
    let max =1;
    let str = s[0];
    
    for(let i=1; i<len; i++) {
        let idx = str.indexOf(ss[i]);
        if(idx >= 0) {
            if(str.length > max) {
                max = str.length;
            }
            str = str.substring(idx+1) + s[i];
        }else{
            str += s[i];
        }
    }
    if(str.length > max) {
        max = str.length;
    }
    
    return max;
}

具体题解以及其他解决方法可查看leetcode3