前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小鹏三面,一道 Hard 结束

小鹏三面,一道 Hard 结束

作者头像
五分钟学算法
发布2024-05-10 15:43:42
1060
发布2024-05-10 15:43:42
举报
文章被收录于专栏:五分钟学算法五分钟学算法

大家好,我是吴师兄。

一般来说,面试过程有个潜规则,如果面试官对你很满意,在算法面试环节往往会给你出一道简单题或者送分题,如果觉得不满意,则会让你手撕一道 Hard 题,让你觉得是因为这个环节表现不佳被拒。

有个网友在小鹏三面,遇到了矩形面积这道 Hard 题,没做出来,导致被拒。

底下评论大部分都是认为面试官就是不想要了,才出这样一道算法题。

有读者朋友在面试过程中手撕成功过这道算法题么?

继续今天的算法学习,来一个 Hard 的算法题:基本计算器

一、题目描述

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

示例 1:

代码语言:javascript
复制
输入:s = "1 + 1"
输出:2

示例 2:

代码语言:javascript
复制
输入:s = " 2-1 + 2 "
输出:3

示例 3:

代码语言:javascript
复制
输入:s = "(1+(4+5+2)-3)+(6+8)"
输出:23

提示:

  • 1 <= s.length <= 3 * 105
  • s 由数字、'+''-''('')'、和 ' ' 组成
  • s 表示一个有效的表达式

二、题目解析

算法考察点
  1. 栈的应用:使用栈来处理括号的计算顺序。
  2. 字符串处理:对字符串表达式进行遍历和字符的转换。
  3. 计算逻辑:根据括号的计算顺序,正确计算表达式的结果。
算法思路
  1. 使用一个栈来存储数字和括号外的运算符。
  2. 从左到右遍历字符串表达式,依次处理每个字符:
    • 如果是数字,则将其转换为整数并入栈。
    • 如果是运算符,则更新当前的符号。
    • 如果是左括号,则将当前结果和符号入栈,并初始化结果和符号。
    • 如果是右括号,则将栈顶的符号和结果出栈,计算括号内的结果,并将结果与栈顶的结果相加。
  3. 遍历完整个表达式后,栈顶元素即为计算结果。

三、参考代码

代码语言:javascript
复制
// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 基本计算器( LeetCode 224 ):https://leetcode-cn.com/problems/basic-calculator
class Solution {
    public int calculate(String s) {

        // 使用栈来储存字符串表达式中的数字
        Stack<Integer> stack = new Stack<Integer>();

        // 为了方便计算,所有的操作都视为加法操作
        // 那么原先的减法操作就相当于是加一个负数
        // 默认都是正数
        int sign = 1;

        // 保存计算的结果
        int res = 0;

        // 获取字符串的长度,然后获取里面的每个字符
        int length = s.length();

        // 获取字符串里面的每个字符
        for (int i = 0; i < length; i++) {

            // 获取此时的字符
            char ch = s.charAt(i);

            // 如果当前字符是数字的话
            if (Character.isDigit(ch)) {

                // 那么可以通过 - '0' 这个操作把字符转换为整数
                // 相当于转换成了 ascii 码进行的数字运算
                int value = ch - '0';

                // 去查看当前字符的后一位是否存在
                // 如果操作并且后一位依旧是数字,那么就需要把后面的数字累加上来

                while (i + 1 < length && Character.isDigit(s.charAt(i + 1))){
                    
                    // i 向后移动,直到遇到非数字为止
                    i++;

                    // i 每向后移动一位,当前的值就需要乘以 10
                    // 比如 s 为 "123+456"
                    // 此时 i = 0,那么 value 为 1
                    // i = 1,那么 value 为 1 * 10 + 2 = 12
                    // i = 2,那么 value 为 12 * 10 + 3 = 123
                    value = value * 10 + s.charAt(i) - '0';

                }

                // 那么把获取到的数累加到结果 res 上
                res = res + sign * value;

              // 如果是 '+'
            } else if (ch == '+') {
                
                // 那么说明直接加一个正数
                sign = 1;

              // 如果是 '-'
            } else if (ch == '-') {

                // 那么说明加一个负数
                sign = -1;

              // 如果是 '('
            } else if (ch == '(') {
                // 根据数学计算规则,需要先计算括号里面的数字
                // 而什么时候计算呢?
                // 遇到 ) 为止
                // 所以,在遇到 ) 之前需要把之前计算好的结果存储起来再计算
                // ( ) 直接的计算规则和一开始是一样的

                // 1、先把 ( 之前的结果存放到栈中
                stack.push(res);

                // 2、重新初始化 res 为 0
                res = 0;
                // 3、把 ( 左边的操作符号存放到栈中
                // 比如如果是 5 - ( 2 + 3 ) ,那么就是把 -1 存放进去
                // 比如如果是 5 +( 2 + 3 ) ,那么就是把 1 存放进去
                stack.push(sign);

                // 4、为了方便计算,所有的操作都视为加法操作
                // 那么原先的减法操作就相当于是加一个负数
                // 默认都是正数
                sign = 1;

                // 如果是 ')'
            } else if (ch == ')') {
                
                // 那么就需要把栈中存放的元素取出来了
                // 在 ch == '(' 这个判断语句中,每次都会往栈中存放两个元素
                // 1、先存放左括号外面的结果
                // 2、再存放左括号外面的符号

                // 1、先获取栈顶元素,即左括号外面的符号,查看是 + 还是 -
                int formerSign = stack.peek();

                // 把栈顶元素弹出
                stack.pop();

                // 2、再获取栈顶元素,即左括号结果
                int formerRes = stack.peek();

                // 把栈顶元素弹出
                stack.pop();

                // 那结果就是括号外面的结果 + 括号里面的结果,至于是加正数还是负数,取决于左括号外面的符号
                res = formerRes +  formerSign * res ;

            }
        }

        // 返回计算好的结果
        return res;
    }
}

ending

我总结并录制了 100 道 LeetCode 高频算法题,涵盖了数组、链表、栈、队列、二叉树、回溯算法、动态规划等众多高频知识点,所选的题目也是非常有特征的题目,一题抵十题。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 五分钟学算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目描述
  • 二、题目解析
    • 算法考察点
      • 算法思路
      • 三、参考代码
      • ending
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档