算法打卡-leetcode-20210325

144 阅读2分钟

1. 计算器

给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。
表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格  。 整数除法仅保留整数部分。

我的想法是遍历字符串先整合数字为一个完整整数,然后根据运算符优先级计算值。
我使用了两种方法,一种就是使用标志位在一个数组完成计算,另外一种就是使用数组方法满足计算需求。

var calculate = function (s) {
    // 计算
    const cal = (num1, opera, num2) => {
        let result;
        num1 = parseInt(num1);
        num2 = parseInt(num2);

        switch (opera) {
            case "+":
                result = num1 + num2;
                break;
            case "-":
                result = num1 - num2;
                break;
            case "*":
                result = num1 * num2;
                break;
            case "/":
                result = Math.trunc(num1 / num2);
                break;
        }

        return result;
    }

    // 运算符与数字分类
    let array1 = [];
    let string = s.replace(/\s+/g, "").split("").reduce((pre, cur) => {
        if ("+-*/".indexOf(cur) != -1) {
            array1.push(pre);
            array1.push(cur);
            return "";
        } else {
            return pre + cur;
        }
    }, "");
    array1.push(string);

    // 标志位
    let index1 = 0;
    let index2 = -1;
    while (index1 < array1.length) {
        let value = array1[index1];
        if ("*/".indexOf(value) != -1) {
            ++index1;
            array1[index2] = cal(array1[index2], value, array1[index1]);
        } else {
            ++index2;
            array1[index2] = value;
        }
        ++index1;
    }
    index1 = 0;
    while (index1 < index2) {
        array1[0] = cal(array1[0], array1[++index1], array1[++index1]);
    }

    return array1[0];

    // 数组方法
    // let array2 = [];

    // array1.reverse();
    // while (array1.length > 0) {
    //     let value = array1.pop();
    //     if ("*/".indexOf(value) != -1) {
    //         array2.push(cal(array2.pop(), value, array1.pop()))
    //     } else {
    //         array2.push(value);
    //     }
    // }

    // array2.reverse();
    // let result = array2.pop();

    // while (array2.length > 0) {
    //     result = cal(result, array2.pop(), array2.pop());
    // }

    // return result;
};

image.png

PS: 提供一下比较好的解法。

    var calculate = function(s) {
        let sign = '+', n = 0, c, stack = [];
        for (let i = 0; i <= s.length; i++) {
            c = s.charAt(i);
            if (c === ' ') continue;
            if (c <= '9' && c >= '0') {
                n = n * 10 + parseInt(c);
                continue;
            }
            if (sign === '+') {
                stack.push(n);
            } else if (sign === '-') {
                stack.push(-n);
            } else if (sign === '*') {
                stack.push(stack.pop() * n)
            } else if (sign === '/') {
                stack.push(Math.trunc(stack.pop() / n))
            }
            sign = c;
            n = 0;
        }
        return stack.reduce((acc, n) => acc + n, 0);
    };

题解地址:leetcode-cn.com/problems/ca…

2.每日温度

请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

我只想到暴力破解,然后在看题解时看了单调栈的解法,就自己尝试用代码实现。

var dailyTemperatures = function (T) {
    // 暴力法
    // let array = new Array(T.length).fill(0);
    // for (let i = 0; i < T.length; ++i) {
    //     for (let j = i + 1; j < T.length; ++j) {
    //         if (T[j] > T[i]) {
    //             array[i] = j - i;
    //             break;
    //         }
    //     }
    // }
    // return array;

    // 单调栈
    let array = new Array(T.length).fill(0);
    let stack = [];
    for (let i = T.length - 1; i >= 0; --i) {
        while (stack.length > 0 && T[i] >= T[stack[stack.length - 1]]) {
            stack.pop();
        }
        if (stack.length > 0) {
            array[i] = stack[stack.length - 1] - i;
        }
        stack.push(i);
    }
    return array;
};

image.png